This notebook answers the questions provided on April 18, 2024

# Load the data 
Diet_CombinedData_Clean = readRDS(file = "~/Dropbox (Edison_Lab@UGA)/Projects/vet/Deanna/Golden_Data/CleanCombinedDietData.rds")
# Load the packages needed
library(readxl) #for loading Excel files

library(dplyr) #for data processing/cleaning

library(tidyr) #for data processing/cleaning

library(skimr) #for nice visualization of data 

library(here) #to set paths

library(DT) #nice datatables 

library(ggplot2) #for figures

library(plotly) #for interactive figures

library (openxlsx)

Plot all dogs based on study year

  1. How many individual dogs were in each study year?
# Create a table that shows the frequency of the dogs enrolled by year

unique_count = Diet_CombinedData_Clean %>%  
  distinct(study_year,id) %>%  #count unique values
  group_by(study_year)%>% # count the frequency by calendar year
  summarize ("Freq" = n())%>%
  filter(!is.na(study_year))# dont include any NA

# Print the new BCS table
print(unique_count)
unique_count_datatable = datatable(unique_count, options = list(), class = "display")
unique_count_datatable
NA

Plot

# plot the frequency 
figure1 = ggplot(data=unique_count, aes(x=study_year, y=Freq, group=1)) +
  geom_line()+
  geom_point()+ 
  theme_bw()+
  theme(axis.text.x = element_text(face="bold",  size=10)) + 
  xlab("Study Year") + 
  ylab("Number of Enrolled Goldens") +
  ggtitle("Study enrollment by study year") +
  theme(
  plot.title = element_text(color="Black", size=14, face="bold"))+
  theme(plot.caption = element_text(hjust=0))
figure1


# Convert to an interactive Plotly plot
interactive_fig1 <- ggplotly(figure1)

# Print the interactive plot
interactive_fig1

BCS by study year

  1. Per study year, how many of those individual dogs had a BCS of 0-3
  2. Per study year how many of those individual dogs had a BCS of 4-6
  3. Per study uear how many of those individual dogs had a BCS of 7-9
Diet_CombinedData_Clean$study_year <- factor(Diet_CombinedData_Clean$study_year, levels = c("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"))
# Create a table for the frequency of each Body condition score range by year
BCS_table = Diet_CombinedData_Clean %>%
  distinct(study_year, bcs, id) %>%
  filter(!is.na(study_year), !is.na(bcs)) %>% # Filter out NA values in calendaryear and bcs
  mutate(BCS_Range = case_when(
    bcs >= 0 & bcs <= 3 ~ "Low BCS (0-3)",
    bcs >= 4 & bcs <= 6 ~ "Normal BCS (4-6)",
    bcs >= 7 & bcs <= 9 ~ "High BCS (7-9)",
    TRUE ~ "Unknown" # Handle any out of range or unexpected values
  )) %>%
  group_by(study_year, BCS_Range) %>%
  summarize(Freq = n(), .groups = 'drop') # Calculate frequency

# Print the new BCS table
print(BCS_table)
BCS_datatable = datatable(BCS_table, options = list(), class = "display")
BCS_datatable

# Plot the frequency using ggplot
figure2 = ggplot(data=BCS_table, aes(x=study_year, y=Freq, group=BCS_Range, color=BCS_Range)) +
  geom_line() +
  geom_point() +
  theme_bw() +
  theme(axis.text.x = element_text(face="bold", size=10)) +
  xlab("Study Year") +
  ylab("Number of Dogs") +
  ggtitle("BCS Range by Year") +
  theme(plot.title = element_text(color="Black", size=14, face="bold")) +
  labs(caption = "Figure 2: Number of Dogs with specific body condition score ranges by year.") +
  theme(plot.caption = element_text(hjust=0))

# Convert to an interactive Plotly plot
interactive_fig2 <- ggplotly(figure2)

# Print the interactive plot
interactive_fig2

Processing by study year

  1. How many individual dogs were in each study year that ate:
  1. Minimally processed
  2. Processed
  3. Ultra-processed
# Create a table for the frequency of each Body condition score range by year
processing_table = Diet_CombinedData_Clean %>%
  distinct(study_year, process.category, id)%>%  # Filter out NA values in study_year and process.category
  filter(!process.category %in% c("N/A", "UNK", "TBD")) %>%
  filter(!is.na(study_year), !is.na(process.category)) %>% # Filter out NA values in calendaryear and bcs
  group_by(study_year, process.category) %>%
  summarize(Freq = n(), .groups = 'drop') # Calculate frequency

# Print the new BCS table
print(processing_table)
processing_datatable = datatable(processing_table, options = list(), class = "display")
processing_datatable

# Plot the frequency using ggplot
figure3 = ggplot(data=processing_table, aes(x=study_year, y=Freq, group=process.category, color=process.category)) +
  geom_line() +
  geom_point() +
  theme_bw() +
  theme(axis.text.x = element_text(face="bold", size=10)) +
  xlab("Study Year") +
  ylab("Number of Dogs") +
  ggtitle("Processing Categorization by Study Year") +
  theme(plot.title = element_text(color="Black", size=14, face="bold")) +
  labs(caption = "Figure 2: Number of Dogs with specific body condition score ranges by year.") +
  theme(plot.caption = element_text(hjust=0))

# Convert to an interactive Plotly plot
interactive_fig3 <- ggplotly(figure3)

# Print the interactive plot
interactive_fig3

Cardiovascular

#load data
project.path = here()

Combined_Data.location = here::here("1_Data","Raw_data","Diagnosis","cardiovascular.csv")

# load the data 

cardiovascular = read.csv(Combined_Data.location)

#make all the names lowercase
names(cardiovascular)<-tolower(names(cardiovascular))
#add unique IDs
cardiovascular$unique_id = paste(cardiovascular$id, "_", cardiovascular$study_year)

#relocate to begining

cardiovascular = cardiovascular %>%

  relocate(unique_id, .before = id)

#Check 

#dplyr::glimpse(cardiovascular)

#skimr::skim(cardiovascular)

# Check study ID

# According to our data source, there were 3044 dogs apart of the study

Unique_Identifiers = unique(cardiovascular$id)

length(Unique_Identifiers)
[1] 3044
#check study Year

# according to our data souce, dogs can be apart of the study for a maximum of 10 years, the bsaeline is 0 and should be in whole number

(unique(cardiovascular$study_year))
 [1]  0  1  2  3  4  5  6  7  8  9 10
#rename any column
cardiovascular = cardiovascular %>% 
 rename("any_cardio" = "any")

Add to diet data

# Select only the unique_id and any columns from cardiovascular
cardiovascular_reduced <- cardiovascular %>% 
  select(unique_id, any_cardio)
# Joining the reduced cardiovascular data 
Diet_CombineData_Updated <- Diet_CombinedData_Clean %>%
  left_join(cardiovascular_reduced, by = "unique_id")

Endocrine

#load data
project.path = here()

Combined_Data.location = here::here("1_Data","Raw_data","Diagnosis","endocrine.csv")

# load the data 

endocrine = read.csv(Combined_Data.location)

#make all the names lowercase
names(endocrine)<-tolower(names(endocrine))
#add unique IDs
endocrine$unique_id = paste(endocrine$id, "_", endocrine$study_year)

#relocate to begining

endocrine = endocrine %>%

  relocate(unique_id, .before = id)

#Check 

#dplyr::glimpse(endocrine)

#skimr::skim(endocrine)

# Check study ID

# According to our data source, there were 3044 dogs apart of the study

Unique_Identifiers = unique(endocrine$id)

length(Unique_Identifiers)
[1] 3044
#check study Year

# according to our data souce, dogs can be apart of the study for a maximum of 10 years, the bsaeline is 0 and should be in whole number

(unique(endocrine$study_year))
 [1]  0  1  2  3  4  5  6  7  8  9 10
#rename any column
endocrine = endocrine %>% 
 rename("any_endocrine" = "any")

Add to diet data

# Select only the unique_id and any columns from cardiovascular
endocrine_reduced <- endocrine %>% 
  select(unique_id, any_endocrine)
# Joining the reduced cardiovascular data 
Diet_CombineData_Updated <- Diet_CombineData_Updated %>%
  left_join(endocrine_reduced, by = "unique_id")

Gastrointestinal

#load data
project.path = here()

Data.location = here::here("1_Data","Raw_data","Diagnosis","gastrointestinal.csv")

# load the data 

gastrointestinal = read.csv(Data.location)

#make all the names lowercase
names(gastrointestinal)<-tolower(names(gastrointestinal))
#add unique IDs
gastrointestinal$unique_id = paste(gastrointestinal$id, "_", gastrointestinal$study_year)

#relocate to begining

gastrointestinal = gastrointestinal %>%

  relocate(unique_id, .before = id)

#Check 

#dplyr::glimpse(gastrointestinal)

#skimr::skim(gastrointestinal)

# Check study ID

# According to our data source, there were 3044 dogs apart of the study

Unique_Identifiers = unique(gastrointestinal$id)

length(Unique_Identifiers)
[1] 3044
#check study Year

# according to our data souce, dogs can be apart of the study for a maximum of 10 years, the bsaeline is 0 and should be in whole number

(unique(gastrointestinal$study_year))
 [1]  0  1  2  3  4  5  6  7  8  9 10
#rename any column
gastrointestinal = gastrointestinal %>% 
 rename("any_gastrointestinal" = "any")

Add to diet data

# Select only the unique_id and any columns from cardiovascular
gastrointestinal_reduced <- gastrointestinal %>% 
  select(unique_id, any_gastrointestinal)
# Joining the reduced cardiovascular data 
Diet_CombineData_Updated <- Diet_CombineData_Updated %>%
  left_join(gastrointestinal_reduced, by = "unique_id")

Hematologic

#load data
project.path = here()

Data.location = here::here("1_Data","Raw_data","Diagnosis","hematologic.csv")

# load the data 

hematologic = read.csv(Data.location)

#make all the names lowercase
names(hematologic)<-tolower(names(hematologic))
#add unique IDs
hematologic$unique_id = paste(hematologic$id, "_", hematologic$study_year)

#relocate to begining

hematologic = hematologic %>%

  relocate(unique_id, .before = id)

#Check 

#dplyr::glimpse(hematologic)

#skimr::skim(hematologic)

# Check study ID

# According to our data source, there were 3044 dogs apart of the study

Unique_Identifiers = unique(hematologic$id)

length(Unique_Identifiers)
[1] 3044
#check study Year

# according to our data souce, dogs can be apart of the study for a maximum of 10 years, the bsaeline is 0 and should be in whole number

(unique(hematologic$study_year))
 [1]  0  1  2  3  4  5  6  7  8  9 10
#rename any column
hematologic = hematologic %>% 
 rename("any_hematologic" = "any")

Add to diet data

# Select only the unique_id and any columns from cardiovascular
hematologic_reduced <- hematologic %>% 
  select(unique_id, any_hematologic)
# Joining the reduced cardiovascular data 
Diet_CombineData_Updated <- Diet_CombineData_Updated %>%
  left_join(hematologic_reduced, by = "unique_id")

musculoskeletal

#load data
project.path = here()

Data.location = here::here("1_Data","Raw_data","Diagnosis","musculoskeletal.csv")

# load the data 

musculoskeletal = read.csv(Data.location)

#make all the names lowercase
names(musculoskeletal)<-tolower(names(musculoskeletal))
#add unique IDs
musculoskeletal$unique_id = paste(musculoskeletal$id, "_", musculoskeletal$study_year)

#relocate to begining

musculoskeletal = musculoskeletal %>%

  relocate(unique_id, .before = id)

#Check 

#dplyr::glimpse(musculoskeletal)

#skimr::skim(musculoskeletal)

# Check study ID

# According to our data source, there were 3044 dogs apart of the study

Unique_Identifiers = unique(musculoskeletal$id)

length(Unique_Identifiers)
[1] 3044
#check study Year

# according to our data souce, dogs can be apart of the study for a maximum of 10 years, the bsaeline is 0 and should be in whole number

(unique(musculoskeletal$study_year))
 [1]  0  1  2  3  4  5  6  7  8  9 10
#rename any column
musculoskeletal = musculoskeletal %>% 
 rename("any_musculoskeletal" = "any")

Add to diet data

# Select only the unique_id and any columns from cardiovascular
musculoskeletal_reduced <- musculoskeletal %>% 
  select(unique_id, any_musculoskeletal)
# Joining the reduced cardiovascular data 
Diet_CombineData_Updated <- Diet_CombineData_Updated %>%
  left_join(musculoskeletal_reduced, by = "unique_id")

Nervous

#load data
project.path = here()

Data.location = here::here("1_Data","Raw_data","Diagnosis","nervous.csv")

# load the data 

nervous = read.csv(Data.location)

#make all the names lowercase
names(nervous)<-tolower(names(nervous))
#add unique IDs
nervous$unique_id = paste(nervous$id, "_", nervous$study_year)

#relocate to begining

nervous = nervous %>%

  relocate(unique_id, .before = id)

#Check 

#dplyr::glimpse(nervous)

#skimr::skim(nervous)

# Check study ID

# According to our data source, there were 3044 dogs apart of the study

Unique_Identifiers = unique(nervous$id)

length(Unique_Identifiers)
[1] 3044
#check study Year

# according to our data souce, dogs can be apart of the study for a maximum of 10 years, the bsaeline is 0 and should be in whole number

(unique(nervous$study_year))
 [1]  0  1  2  3  4  5  6  7  8  9 10
#rename any column
nervous = nervous %>% 
 rename("any_nervous" = "any")

Add to diet data

# Select only the unique_id and any columns from cardiovascular
nervous_reduced <- nervous %>% 
  select(unique_id, any_nervous)
# Joining the reduced cardiovascular data 
Diet_CombineData_Updated <- Diet_CombineData_Updated %>%
  left_join(nervous_reduced, by = "unique_id")

Urinary

#load data
project.path = here()

Data.location = here::here("1_Data","Raw_data","Diagnosis","urinary.csv")

# load the data 

urinary = read.csv(Data.location)

#make all the names lowercase
names(urinary)<-tolower(names(urinary))
#add unique IDs
urinary$unique_id = paste(urinary$id, "_", urinary$study_year)

#relocate to begining

urinary = urinary %>%

  relocate(unique_id, .before = id)

#Check 

#dplyr::glimpse(urinary)

#skimr::skim(urinary)

# Check study ID

# According to our data source, there were 3044 dogs apart of the study

Unique_Identifiers = unique(urinary$id)

length(Unique_Identifiers)
[1] 3044
#check study Year

# according to our data souce, dogs can be apart of the study for a maximum of 10 years, the bsaeline is 0 and should be in whole number

(unique(urinary$study_year))
 [1]  0  1  2  3  4  5  6  7  8  9 10
#rename any column
urinary = urinary %>% 
 rename("any_urinary" = "any")

Add to diet data

# Select only the unique_id and any columns from cardiovascular
urinary_reduced <- urinary %>% 
  select(unique_id, any_urinary)
# Joining the reduced cardiovascular data 
Diet_CombineData_Updated <- Diet_CombineData_Updated %>%
  left_join(urinary_reduced, by = "unique_id")

add column to determine if a dog has any major diagnosis

Diet_CombineData_Updated <- Diet_CombineData_Updated %>%
  rowwise() %>%  # Apply the operation row by row
  mutate(any_major_diagnosis = if_else(any_cardio == 1 | any_endocrine == 1 | any_gastrointestinal == 1 | any_musculoskeletal == 1 | any_nervous == 1 | any_urinary == 1 | any_hematologic == 1, 1, 0)) %>%
  ungroup()  # Remove the rowwise grouping

minor diagnosis

Eye

#load data
project.path = here()

Data.location = here::here("1_Data","Raw_data","Diagnosis","eye.csv")

# load the data 

eye = read.csv(Data.location)

#make all the names lowercase
names(eye)<-tolower(names(eye))
#add unique IDs
eye$unique_id = paste(eye$id, "_", eye$study_year)

#relocate to begining

eye = eye %>%

  relocate(unique_id, .before = id)

#Check 

#dplyr::glimpse(eye)

#skimr::skim(eye)

# Check study ID

# According to our data source, there were 3044 dogs apart of the study

Unique_Identifiers = unique(eye$id)

length(Unique_Identifiers)
[1] 3044
#check study Year

# according to our data souce, dogs can be apart of the study for a maximum of 10 years, the bsaeline is 0 and should be in whole number

(unique(eye$study_year))
 [1]  0  1  2  3  4  5  6  7  8  9 10
#rename any column
eye = eye %>% 
 rename("any_eye" = "any")

Add to diet data

# Select only the unique_id and any columns from cardiovascular
eye_reduced <- eye %>% 
  select(unique_id, any_eye)
# Joining the reduced cardiovascular data 
Diet_CombineData_Updated <- Diet_CombineData_Updated %>%
  left_join(eye_reduced, by = "unique_id")

Infection

#load data
project.path = here()

Data.location = here::here("1_Data","Raw_data","Diagnosis","infectious.csv")

# load the data 

infectious = read.csv(Data.location)

#make all the names lowercase
names(infectious)<-tolower(names(infectious))
#add unique IDs
infectious$unique_id = paste(infectious$id, "_", infectious$study_year)

#relocate to begining

infectious = infectious %>%

  relocate(unique_id, .before = id)

#Check 

#dplyr::glimpse(infectious)

#skimr::skim(infectious)

# Check study ID

# According to our data source, there were 3044 dogs apart of the study

Unique_Identifiers = unique(infectious$id)

length(Unique_Identifiers)
[1] 3044
#check study Year

# according to our data souce, dogs can be apart of the study for a maximum of 10 years, the bsaeline is 0 and should be in whole number

(unique(infectious$study_year))
 [1]  0  1  2  3  4  5  6  7  8  9 10
#rename any column
infectious = infectious %>% 
 rename("any_infectious" = "any")

Add to diet data

# Select only the unique_id and any columns from cardiovascular
infectious_reduced <- infectious %>% 
  select(unique_id, any_infectious)
# Joining the reduced cardiovascular data 
Diet_CombineData_Updated <- Diet_CombineData_Updated %>%
  left_join(infectious_reduced, by = "unique_id")

skin

#load data
project.path = here()

Data.location = here::here("1_Data","Raw_data","Diagnosis","skin.csv")

# load the data 

skin = read.csv(Data.location)

#make all the names lowercase
names(skin)<-tolower(names(skin))
#add unique IDs
skin$unique_id = paste(skin$id, "_", skin$study_year)

#relocate to begining

skin = skin %>%

  relocate(unique_id, .before = id)

#Check 

#dplyr::glimpse(skin)

#skimr::skim(skin)

# Check study ID

# According to our data source, there were 3044 dogs apart of the study

Unique_Identifiers = unique(skin$id)

length(Unique_Identifiers)
[1] 3044
#check study Year

# according to our data souce, dogs can be apart of the study for a maximum of 10 years, the bsaeline is 0 and should be in whole number

(unique(skin$study_year))
 [1]  0  1  2  3  4  5  6  7  8  9 10
#rename any column
skin = skin %>% 
 rename("any_skin" = "any")

Add to diet data

# Select only the unique_id and any columns from cardiovascular
skin_reduced <- skin %>% 
  select(unique_id, any_skin)
# Joining the reduced cardiovascular data 
Diet_CombineData_Updated <- Diet_CombineData_Updated %>%
  left_join(skin_reduced, by = "unique_id")

reproductive

#load data
project.path = here()

Data.location = here::here("1_Data","Raw_data","Diagnosis","reproductive.csv")

# load the data 

reproductive = read.csv(Data.location)

#make all the names lowercase
names(reproductive)<-tolower(names(reproductive))
#add unique IDs
reproductive$unique_id = paste(reproductive$id, "_", reproductive$study_year)

#relocate to begining

reproductive = reproductive %>%

  relocate(unique_id, .before = id)

#Check 

#dplyr::glimpse(reproductive)

#skimr::skim(reproductive)

# Check study ID

# According to our data source, there were 3044 dogs apart of the study

Unique_Identifiers = unique(reproductive$id)

length(Unique_Identifiers)
[1] 3044
#check study Year

# according to our data souce, dogs can be apart of the study for a maximum of 10 years, the bsaeline is 0 and should be in whole number

(unique(reproductive$study_year))
 [1]  0  1  2  3  4  5  6  7  8  9 10
#rename any column
reproductive = reproductive %>% 
 rename("any_reproductive" = "any")

Add to diet data

# Select only the unique_id and any columns from cardiovascular
reproductive_reduced <- reproductive %>% 
  select(unique_id, any_reproductive)
# Joining the reduced cardiovascular data 
Diet_CombineData_Updated <- Diet_CombineData_Updated %>%
  left_join(reproductive_reduced, by = "unique_id")

dental

#load data
project.path = here()

Data.location = here::here("1_Data","Raw_data","Diagnosis","dental.csv")

# load the data 

dental = read.csv(Data.location)

#make all the names lowercase
names(dental)<-tolower(names(dental))
#add unique IDs
dental$unique_id = paste(dental$id, "_", dental$study_year)

#relocate to begining

dental = dental %>%

  relocate(unique_id, .before = id)

#Check 

#dplyr::glimpse(dental)

#skimr::skim(dental)

# Check study ID

# According to our data source, there were 3044 dogs apart of the study

Unique_Identifiers = unique(dental$id)

length(Unique_Identifiers)
[1] 3044
#check study Year

# according to our data souce, dogs can be apart of the study for a maximum of 10 years, the bsaeline is 0 and should be in whole number

(unique(dental$study_year))
 [1]  0  1  2  3  4  5  6  7  8  9 10
#rename any column
dental = dental %>% 
 rename("any_dental" = "any")

Add to diet data

# Select only the unique_id and any columns from cardiovascular
dental_reduced <- dental %>% 
  select(unique_id, any_dental)
# Joining the reduced cardiovascular data 
Diet_CombineData_Updated <- Diet_CombineData_Updated %>%
  left_join(dental_reduced, by = "unique_id")

ear nose throat

#load data
project.path = here()

Data.location = here::here("1_Data","Raw_data","Diagnosis","ear_nose_throat.csv")

# load the data 

ear_nose_throat = read.csv(Data.location)

#make all the names lowercase
names(ear_nose_throat)<-tolower(names(ear_nose_throat))
#add unique IDs
ear_nose_throat$unique_id = paste(ear_nose_throat$id, "_", ear_nose_throat$study_year)

#relocate to begining

ear_nose_throat = ear_nose_throat %>%

  relocate(unique_id, .before = id)

#Check 

#dplyr::glimpse(ear_nose_throat)

#skimr::skim(ear_nose_throat)

# Check study ID

# According to our data source, there were 3044 dogs apart of the study

Unique_Identifiers = unique(ear_nose_throat$id)

length(Unique_Identifiers)
[1] 3044
#check study Year

# according to our data souce, dogs can be apart of the study for a maximum of 10 years, the bsaeline is 0 and should be in whole number

(unique(ear_nose_throat$study_year))
 [1]  0  1  2  3  4  5  6  7  8  9 10
#rename any column
ear_nose_throat = ear_nose_throat %>% 
 rename("any_ear_nose_throat" = "any")

Add to diet data

# Select only the unique_id and any columns from cardiovascular
ear_nose_throat_reduced <- ear_nose_throat %>% 
  select(unique_id, any_ear_nose_throat)
# Joining the reduced cardiovascular data 
Diet_CombineData_Updated <- Diet_CombineData_Updated %>%
  left_join(ear_nose_throat_reduced, by = "unique_id")

add column to determine if a dog has any minor diagnosis

Diet_CombineData_Updated = Diet_CombineData_Updated %>%
  rowwise() %>%  # Apply the operation row by row
  mutate(any_minor_diagnosis = if_else(any_eye == 1 | any_dental == 1 | any_ear_nose_throat == 1 | any_reproductive == 1 | any_infectious == 1 | any_skin == 1, 1, 0)) %>%
  ungroup()  # Remove the rowwise grouping

add column to determine if a dog has any diagnosis

Diet_CombineData_Updated = Diet_CombineData_Updated %>%
  rowwise() %>%  # Apply the operation row by row
  mutate(any_diagnosis = if_else(any_cardio == 1 | any_endocrine == 1 | any_gastrointestinal == 1 | any_musculoskeletal == 1 | any_nervous == 1 | any_nervous == 1 | any_urinary == 1 | any_eye == 1 | any_ear_nose_throat == 1 | any_infectious == 1 | any_skin == 1 | any_urinary ==1, 1, 0)) %>%
  ungroup()  # Remove the rowwise grouping

Major minor and diagnosis

# Summarize data to get counts of diagnosis vs. no diagnosis by study_year
#minor_diagnosis_summary <- Diet_CombineData_Updated %>%
#   filter(!is.na(any_minor_diagnosis)) %>%
#  group_by(study_year, any_minor_diagnosis) %>%
#  summarize(Frequency = n(), .groups = 'drop') %>%
#  mutate(any_minor_diagnosis = factor(any_minor_diagnosis, levels = c(0, 1), labels = c("No Diagnosis", "Diagnosis")))
#minor_diagnosis_summary


# Update the table to include BCS ranges
minor_diagnosis_summary <- Diet_CombineData_Updated %>%
  filter(!is.na(any_minor_diagnosis)) %>%
  filter(!is.na(bcs)) %>%
  mutate(BCS_Range = case_when(
    bcs >= 0 & bcs <= 3 ~ "Low BCS (0-3)",
    bcs >= 4 & bcs <= 6 ~ "Normal BCS (4-6)",
    bcs >= 7 & bcs <= 9 ~ "High BCS (7-9)",
    TRUE ~ "Unknown" 
  )) %>%
  group_by(study_year, BCS_Range, any_minor_diagnosis) %>%
  summarize(Frequency = n(), .groups = 'drop') %>%
  mutate(any_minor_diagnosis = factor(any_minor_diagnosis, levels = c(0, 1), labels = c("No Diagnosis", "Diagnosis")))

# Print the updated summary
print(minor_diagnosis_summary)

minor_diagnosis_summary_datatable = datatable(minor_diagnosis_summary, options = list(), class = "display")
minor_diagnosis_summary_datatable
# Summarize data to get counts of diagnosis vs. no diagnosis by study_year
#major_diagnosis_summary <- Diet_CombineData_Updated %>%
#   filter(!is.na(any_major_diagnosis)) %>%
#  group_by(study_year, any_major_diagnosis) %>%
#  summarize(Frequency = n(), .groups = 'drop') %>%
#  mutate(any_major_diagnosis = factor(any_major_diagnosis, levels = c(0, 1), labels = c("No Diagnosis", "Diagnosis")))
#major_diagnosis_summary


# Update the table to include BCS ranges
major_diagnosis_summary <- Diet_CombineData_Updated %>%
  filter(!is.na(any_major_diagnosis)) %>%
  filter(!is.na(bcs)) %>%
  mutate(BCS_Range = case_when(
    bcs >= 0 & bcs <= 3 ~ "Low BCS (0-3)",
    bcs >= 4 & bcs <= 6 ~ "Normal BCS (4-6)",
    bcs >= 7 & bcs <= 9 ~ "High BCS (7-9)",
    TRUE ~ "Unknown" 
  )) %>%
  group_by(study_year, BCS_Range, any_major_diagnosis) %>%
  summarize(Frequency = n(), .groups = 'drop') %>%
  mutate(any_major_diagnosis = factor(any_major_diagnosis, levels = c(0, 1), labels = c("No Diagnosis", "Diagnosis")))

# Print the updated summary
print(major_diagnosis_summary)

major_diagnosis_summary_datatable = datatable(major_diagnosis_summary, options = list(), class = "display")
major_diagnosis_summary_datatable
# Any diagnosis

# Update the table to include BCS ranges
diagnosis_summary <- Diet_CombineData_Updated %>%
  filter(!is.na(any_diagnosis)) %>%
  filter(!is.na(bcs)) %>%
  mutate(BCS_Range = case_when(
    bcs >= 0 & bcs <= 3 ~ "Low BCS (0-3)",
    bcs >= 4 & bcs <= 6 ~ "Normal BCS (4-6)",
    bcs >= 7 & bcs <= 9 ~ "High BCS (7-9)",
    TRUE ~ "Unknown" 
  )) %>%
  group_by(study_year, BCS_Range, any_diagnosis) %>%
  summarize(Frequency = n(), .groups = 'drop') %>%
  mutate(any_diagnosis = factor(any_diagnosis, levels = c(0, 1), labels = c("No Diagnosis", "Diagnosis")))

# Print the updated summary
print(diagnosis_summary)

diagnosis_summary_datatable = datatable(diagnosis_summary, options = list(), class = "display")
diagnosis_summary_datatable
# Create the bar plot
major_plot <- ggplot(major_diagnosis_summary, aes(x = study_year, y = Frequency, fill = any_major_diagnosis, group = )) +
  geom_bar(stat = "identity", position = "dodge") + facet_wrap(~BCS_Range)+ # Use dodge position to place bars side by side
  labs(title = "Frequency of  Major Diagnosis by Study Year",
       x = "Study Year",
       y = "Frequency",
       fill = "Diagnosis Status") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))  # Rotate x-axis labels for readability

# Display the plot
print(major_plot)


# Convert to an interactive Plotly plot
interactive_fig4 <- ggplotly(major_plot)

interactive_fig4 <- interactive_fig4 %>%
  layout(legend = list(orientation = "h", x = 0.5, xanchor = "center", y = 1.1))

# Print the interactive plot
interactive_fig4
# Create the bar plot
minor_plot <- ggplot(minor_diagnosis_summary, aes(x = study_year, y = Frequency, fill = any_minor_diagnosis)) +
  geom_bar(stat = "identity", position = "dodge") + facet_wrap(~BCS_Range) +  # Use dodge position to place bars side by side
  labs(title = "Frequency of Minor Diagnosis by Study Year ",
       x = "Study Year",
       y = "Frequency",
       fill = "Diagnosis Status") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1), legend.position = "top")  # Rotate x-axis labels for readability

# Display the plot
print(minor_plot)


# Convert to an interactive Plotly plot
interactive_fig5 <- ggplotly(minor_plot)


interactive_fig5 <- interactive_fig5 %>%
  layout(legend = list(orientation = "h", x = 0.5, xanchor = "center", y = 1.1))

# Print the interactive plot
interactive_fig5
NA
# Create the bar plot
diagnosis_plot <- ggplot(diagnosis_summary, aes(x = study_year, y = Frequency, fill = any_diagnosis, group = )) +
  geom_bar(stat = "identity", position = "dodge") + facet_wrap(~BCS_Range)+ # Use dodge position to place bars side by side
  labs(title = "Frequency of Diagnosis by Study Year",
       x = "Study Year",
       y = "Frequency",
       fill = "Diagnosis Status") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))  # Rotate x-axis labels for readability

# Display the plot
print(major_plot)


# Convert to an interactive Plotly plot
interactive_fig6 <- ggplotly(diagnosis_plot)

interactive_fig6 <- interactive_fig6 %>%
  layout(legend = list(orientation = "h", x = 0.5, xanchor = "center", y = 1.1))

# Print the interactive plot
interactive_fig6

Filter the dogs based on Age, bcs, and diagnosis

Determine the number of dogs that have a BCS of 4,5, or 6 between the age of 0-3, 4-6 , 7+ that are generally healthy on a minimally processed diet

# Filter Diet_Data_Clean for age and BCS conditions
#eligible_young_dogs <- Diet_Data_Clean %>%
#  filter(visit.age < 3, BCS_numeric < 7)
#length(unique(eligible_young_dogs$id))

# Filter Diet_Data_Clean for age under 3 years and BCS below 7
#eligible_young_dogs <- Diet_CombineData_Updated %>%
##  filter(visit.age < 3, bcs %in% c(4,5,6)) %>%
#  distinct()
#length(unique(eligible_young_dogs$id))

eligible_young_dogs <- Diet_CombineData_Updated %>%
  filter(visit.age <= 3,                # Age under 3 years
         bcs %in% c(4, 5, 6),          # BCS of 4, 5, or 6
         any_major_diagnosis == 0,     # Exclude dogs with any major diagnosis
         process.category == "Minimally Processed") %>%
  distinct()  # Remove duplicates
length(unique(eligible_young_dogs$id))
[1] 176
eligible_mid_dogs <- Diet_CombineData_Updated %>%
  filter(visit.age >3 & visit.age <= 6,                # between 4-6
         bcs %in% c(4, 5, 6),          # BCS of 4, 5, or 6
         any_major_diagnosis == 0,     # Exclude dogs with any major diagnosis
         process.category == "Minimally Processed") %>%
  distinct()  # Remove duplicates
length(unique(eligible_mid_dogs$id))
[1] 169
eligible_old_dogs <- Diet_CombineData_Updated %>%
  filter(visit.age > 7,                # over 7
         bcs %in% c(4, 5, 6),          # BCS of 4, 5, or 6
         any_major_diagnosis == 0,     # Exclude dogs with any major diagnosis
         process.category == "Minimally Processed") %>%
  distinct()  # Remove duplicates
length(unique(eligible_old_dogs$id))
[1] 92
# Get unique IDs from each table
old_ids <- distinct(eligible_old_dogs, id)
mid_ids <- distinct(eligible_mid_dogs, id)
young_ids <- distinct(eligible_young_dogs, id)

# Find common ids across all three tables
common_ids <- intersect(intersect(old_ids$id, mid_ids$id), young_ids$id)
# Find common IDs across all three tables using reduce and intersect
#common_ids <- Reduce(intersect, list(old_ids$id, mid_ids$id, young_ids$id))


eligible_dogs <- bind_rows(
  filter(eligible_old_dogs, id %in% common_ids),
  filter(eligible_mid_dogs, id %in% common_ids),
  filter(eligible_young_dogs, id %in% common_ids)
)


eligible_dogs1_datatable = datatable(eligible_dogs, options = list(), class = "display")
eligible_dogs1_datatable
length(unique(eligible_dogs$id))
[1] 49

Determine the number of dogs that have a BCS of 4,5, or 6 between the age of 0-3, 4-6 , 7+ that are generally healthy on a ultra processed diet

# Filter Diet_Data_Clean for age and BCS conditions
#eligible_young_dogs <- Diet_Data_Clean %>%
#  filter(visit.age < 3, BCS_numeric < 7)
#length(unique(eligible_young_dogs$id))

# Filter Diet_Data_Clean for age under 3 years and BCS below 7
#eligible_young_dogs <- Diet_CombineData_Updated %>%
##  filter(visit.age < 3, bcs %in% c(4,5,6)) %>%
#  distinct()
#length(unique(eligible_young_dogs$id))

eligible_young_dogs <- Diet_CombineData_Updated %>%
  filter(visit.age <= 3,                # Age under 3 years
         bcs %in% c(4, 5, 6),          # BCS of 4, 5, or 6
         any_major_diagnosis == 0,     # Exclude dogs with any major diagnosis
         process.category == "Ultra Processed") %>%
  distinct()  # Remove duplicates
length(unique(eligible_young_dogs$id))
[1] 2340
eligible_mid_dogs <- Diet_CombineData_Updated %>%
  filter(visit.age >3 & visit.age <= 6,                # between 4-6
         bcs %in% c(4, 5, 6),          # BCS of 4, 5, or 6
         any_major_diagnosis == 0,     # Exclude dogs with any major diagnosis
         process.category == "Ultra Processed") %>%
  distinct()  # Remove duplicates
length(unique(eligible_mid_dogs$id))
[1] 2155
eligible_old_dogs <- Diet_CombineData_Updated %>%
  filter(visit.age > 7,                # over 7
         bcs %in% c(4, 5, 6),          # BCS of 4, 5, or 6
         any_major_diagnosis == 0,     # Exclude dogs with any major diagnosis
         process.category == "Ultra Processed") %>%
  distinct()  # Remove duplicates
length(unique(eligible_old_dogs$id))
[1] 1453
# Get unique IDs from each table
old_ids <- distinct(eligible_old_dogs, id)
mid_ids <- distinct(eligible_mid_dogs, id)
young_ids <- distinct(eligible_young_dogs, id)

# Find common ids across all three tables
common_ids <- intersect(intersect(old_ids$id, mid_ids$id), young_ids$id)
# Find common IDs across all three tables using reduce and intersect
#common_ids <- Reduce(intersect, list(old_ids$id, mid_ids$id, young_ids$id))


eligible_dogs <- bind_rows(
  filter(eligible_old_dogs, id %in% common_ids),
  filter(eligible_mid_dogs, id %in% common_ids),
  filter(eligible_young_dogs, id %in% common_ids)
)
eligible_dogs

#eligible_dogs1_datatable = datatable(eligible_dogs, options = list(), class = "display")
#eligible_dogs1_datatable
length(unique(eligible_dogs$id))
[1] 1078
length(unique(eligible_dogs$id))
[1] 1078
write.xlsx(eligible_dogs, file = "EligibleDogs.xlsx", sheetName = "Data", rowNames = FALSE)

Filter the dogs based on Age, bcs, and diagnosis

# Filter Diet_Data_Clean for age and BCS conditions
#eligible_young_dogs <- Diet_Data_Clean %>%
#  filter(visit.age < 3, BCS_numeric < 7)
#length(unique(eligible_young_dogs$id))

# Filter Diet_Data_Clean for age under 3 years and BCS below 7
#eligible_young_dogs <- Diet_CombineData_Updated %>%
##  filter(visit.age < 3, bcs %in% c(4,5,6)) %>%
#  distinct()
#length(unique(eligible_young_dogs$id))

eligible_young_dogs <- Diet_CombineData_Updated %>%
  filter(visit.age <= 3,                # Age under 3 years
         bcs %in% c(4, 5, 6),          # BCS of 4, 5, or 6
         process.category == "Ultra Processed") %>%
  distinct()  # Remove duplicates
length(unique(eligible_young_dogs$id))
[1] 2737
eligible_mid_dogs <- Diet_CombineData_Updated %>%
  filter(visit.age >3 & visit.age <= 6,                # between 4-6
         bcs %in% c(4, 5, 6),          # BCS of 4, 5, or 6
         process.category == "Ultra Processed") %>%
  distinct()  # Remove duplicates
length(unique(eligible_mid_dogs$id))
[1] 2352
eligible_old_dogs <- Diet_CombineData_Updated %>%
  filter(visit.age > 7,                # over 7
         bcs %in% c(4, 5, 6),          # BCS of 4, 5, or 6
         process.category == "Ultra Processed") %>%
  distinct()  # Remove duplicates
length(unique(eligible_old_dogs$id))
[1] 1734
# Get unique IDs from each table
old_ids <- distinct(eligible_old_dogs, id)
mid_ids <- distinct(eligible_mid_dogs, id)
young_ids <- distinct(eligible_young_dogs, id)

# Find common ids across all three tables
common_ids <- intersect(intersect(old_ids$id, mid_ids$id), young_ids$id)
# Find common IDs across all three tables using reduce and intersect
#common_ids <- Reduce(intersect, list(old_ids$id, mid_ids$id, young_ids$id))


eligible_dogs <- bind_rows(
  filter(eligible_old_dogs, id %in% common_ids),
  filter(eligible_mid_dogs, id %in% common_ids),
  filter(eligible_young_dogs, id %in% common_ids)
)


#eligible_dogs1_datatable = datatable(eligible_dogs, options = list(), class = "display")
#eligible_dogs1_datatable
length(unique(eligible_dogs$id))
[1] 1561
# Filter Diet_Data_Clean for age and BCS conditions
#eligible_young_dogs <- Diet_Data_Clean %>%
#  filter(visit.age < 3, BCS_numeric < 7)
#length(unique(eligible_young_dogs$id))

# Filter Diet_Data_Clean for age under 3 years and BCS below 7
#eligible_young_dogs <- Diet_CombineData_Updated %>%
##  filter(visit.age < 3, bcs %in% c(4,5,6)) %>%
#  distinct()
#length(unique(eligible_young_dogs$id))

eligible_young_dogs <- Diet_CombineData_Updated %>%
  filter(visit.age <= 3,                # Age under 3 years
         bcs %in% c(7, 8, 9),          # BCS of 4, 5, or 6
         process.category == "Ultra Processed") %>%
  distinct()  # Remove duplicates
length(unique(eligible_young_dogs$id))
[1] 583
eligible_mid_dogs <- Diet_CombineData_Updated %>%
  filter(visit.age >3 & visit.age <= 6,                # between 4-6
         bcs %in% c(7, 8, 9),          # BCS of 4, 5, or 6
         process.category == "Ultra Processed") %>%
  distinct()  # Remove duplicates
length(unique(eligible_mid_dogs$id))
[1] 615
eligible_old_dogs <- Diet_CombineData_Updated %>%
  filter(visit.age > 7,                # over 7
         bcs %in% c(7, 8, 9),          # BCS of 4, 5, or 6
         process.category == "Ultra Processed") %>%
  distinct()  # Remove duplicates
length(unique(eligible_old_dogs$id))
[1] 451
# Get unique IDs from each table
old_ids <- distinct(eligible_old_dogs, id)
mid_ids <- distinct(eligible_mid_dogs, id)
young_ids <- distinct(eligible_young_dogs, id)

# Find common ids across all three tables
common_ids <- intersect(intersect(old_ids$id, mid_ids$id), young_ids$id)
# Find common IDs across all three tables using reduce and intersect
#common_ids <- Reduce(intersect, list(old_ids$id, mid_ids$id, young_ids$id))


eligible_dogs <- bind_rows(
  filter(eligible_old_dogs, id %in% common_ids),
  filter(eligible_mid_dogs, id %in% common_ids),
  filter(eligible_young_dogs, id %in% common_ids)
)


eligible_dogs3_datatable = datatable(eligible_dogs, options = list(), class = "display")
eligible_dogs3_datatable
length(unique(eligible_dogs$id))
[1] 96
# Filter Diet_Data_Clean for age and BCS conditions
#eligible_young_dogs <- Diet_Data_Clean %>%
#  filter(visit.age < 3, BCS_numeric < 7)
#length(unique(eligible_young_dogs$id))

# Filter Diet_Data_Clean for age under 3 years and BCS below 7
#eligible_young_dogs <- Diet_CombineData_Updated %>%
##  filter(visit.age < 3, bcs %in% c(4,5,6)) %>%
#  distinct()
#length(unique(eligible_young_dogs$id))

eligible_young_dogs <- Diet_CombineData_Updated %>%
  filter(visit.age <= 3,                # Age under 3 years
         bcs %in% c(4, 5, 6),          # BCS of 4, 5, or 6
         process.category == "Ultra Processed") %>%
  distinct()  # Remove duplicates
length(unique(eligible_young_dogs$id))
[1] 2737
eligible_mid_dogs <- Diet_CombineData_Updated %>%
  filter(visit.age >3 & visit.age <= 6,                # between 4-6
         bcs %in% c(7, 8, 9),          # BCS of 7 8 or 9
         process.category == "Ultra Processed") %>%
  distinct()  # Remove duplicates
length(unique(eligible_mid_dogs$id))
[1] 615
eligible_old_dogs <- Diet_CombineData_Updated %>%
  filter(visit.age > 7,                # over 7
         bcs %in% c(7, 8, 9),          # BCS of 7 8 or 9
         process.category == "Ultra Processed") %>%
  distinct()  # Remove duplicates
length(unique(eligible_old_dogs$id))
[1] 451
# Get unique IDs from each table
old_ids <- distinct(eligible_old_dogs, id)
mid_ids <- distinct(eligible_mid_dogs, id)
young_ids <- distinct(eligible_young_dogs, id)

# Find common ids across all three tables
common_ids <- intersect(intersect(old_ids$id, mid_ids$id), young_ids$id)
# Find common IDs across all three tables using reduce and intersect
#common_ids <- Reduce(intersect, list(old_ids$id, mid_ids$id, young_ids$id))


eligible_dogs <- bind_rows(
  filter(eligible_old_dogs, id %in% common_ids),
  filter(eligible_mid_dogs, id %in% common_ids),
  filter(eligible_young_dogs, id %in% common_ids)
)


eligible_dogs4_datatable = datatable(eligible_dogs, options = list(), class = "display")
eligible_dogs4_datatable
length(unique(eligible_dogs$id))
[1] 213
# Summarize the data to get counts of diagnoses by study_year
cardio_summary <- Diet_CombineData_Updated %>%
   filter(!is.na(any_cardio)) %>%
  group_by(study_year, any_cardio) %>%
  summarize(Frequency = n(), .groups = 'drop')

# Ensure the 'any' column is a factor for better plotting
cardio_summary$any_cardio <- factor(cardio_summary$any_cardio, levels = c(0, 1), labels = c("No Diagnosis", "Diagnosis"))


cardio_summary_datatable = datatable(cardio_summary, options = list(), class = "display")
cardio_summary_datatable

# Create the bar plot
cardio_plot <- ggplot(cardio_summary, aes(x = study_year, y = Frequency, fill = any_cardio)) +
  geom_bar(stat = "identity", position = "dodge") + # 'dodge' position to place bars side by side
  labs(title = "Frequency of Cardiovascular Diagnoses by Study Year",
       x = "Study Year",
       y = "Number of Dogs",
       fill = "Cardio Diagnosis") +
  scale_fill_brewer(palette = "Set1") + # Optional: Adds color
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1), legend.position = "top") # Improve readability of x-axis labels

# Display the plot
print(cardio_plot)


# Convert to an interactive Plotly plot
interactive_fig4 <- ggplotly(cardio_plot)

# Print the interactive plot
interactive_fig4
NA
save(interactive_fig1,interactive_fig2,interactive_fig3,interactive_fig4,interactive_fig5,interactive_fig6, file = "~/Dropbox (Edison_Lab@UGA)/Projects/vet/Deanna/Golden_Data/figures4.RData")


save(unique_count_datatable, BCS_datatable, processing_datatable,eligible_dogs1_datatable,eligible_dogs3_datatable,eligible_dogs4_datatable,minor_diagnosis_summary_datatable,major_diagnosis_summary_datatable
,diagnosis_summary_datatable, file = "~/Dropbox (Edison_Lab@UGA)/Projects/vet/Deanna/Golden_Data/tables4.RData")
LS0tCnRpdGxlOiAiUXVlc3Rpb25zIGFuc3dlcmVkIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpUaGlzIG5vdGVib29rIGFuc3dlcnMgdGhlIHF1ZXN0aW9ucyBwcm92aWRlZCBvbiBBcHJpbCAxOCwgMjAyNAoKYGBge3J9CiMgTG9hZCB0aGUgZGF0YSAKRGlldF9Db21iaW5lZERhdGFfQ2xlYW4gPSByZWFkUkRTKGZpbGUgPSAifi9Ecm9wYm94IChFZGlzb25fTGFiQFVHQSkvUHJvamVjdHMvdmV0L0RlYW5uYS9Hb2xkZW5fRGF0YS9DbGVhbkNvbWJpbmVkRGlldERhdGEucmRzIikKYGBgCgpgYGB7cn0KIyBMb2FkIHRoZSBwYWNrYWdlcyBuZWVkZWQKbGlicmFyeShyZWFkeGwpICNmb3IgbG9hZGluZyBFeGNlbCBmaWxlcwoKbGlicmFyeShkcGx5cikgI2ZvciBkYXRhIHByb2Nlc3NpbmcvY2xlYW5pbmcKCmxpYnJhcnkodGlkeXIpICNmb3IgZGF0YSBwcm9jZXNzaW5nL2NsZWFuaW5nCgpsaWJyYXJ5KHNraW1yKSAjZm9yIG5pY2UgdmlzdWFsaXphdGlvbiBvZiBkYXRhIAoKbGlicmFyeShoZXJlKSAjdG8gc2V0IHBhdGhzCgpsaWJyYXJ5KERUKSAjbmljZSBkYXRhdGFibGVzIAoKbGlicmFyeShnZ3Bsb3QyKSAjZm9yIGZpZ3VyZXMKCmxpYnJhcnkocGxvdGx5KSAjZm9yIGludGVyYWN0aXZlIGZpZ3VyZXMKCmxpYnJhcnkgKG9wZW54bHN4KQpgYGAKCgojIyBQbG90IGFsbCBkb2dzIGJhc2VkIG9uIHN0dWR5IHllYXIKMS4JSG93IG1hbnkgaW5kaXZpZHVhbCBkb2dzIHdlcmUgaW4gZWFjaCBzdHVkeSB5ZWFyPwpgYGB7cn0KIyBDcmVhdGUgYSB0YWJsZSB0aGF0IHNob3dzIHRoZSBmcmVxdWVuY3kgb2YgdGhlIGRvZ3MgZW5yb2xsZWQgYnkgeWVhcgoKdW5pcXVlX2NvdW50ID0gRGlldF9Db21iaW5lZERhdGFfQ2xlYW4gJT4lICAKICBkaXN0aW5jdChzdHVkeV95ZWFyLGlkKSAlPiUgICNjb3VudCB1bmlxdWUgdmFsdWVzCiAgZ3JvdXBfYnkoc3R1ZHlfeWVhciklPiUgIyBjb3VudCB0aGUgZnJlcXVlbmN5IGJ5IGNhbGVuZGFyIHllYXIKICBzdW1tYXJpemUgKCJGcmVxIiA9IG4oKSklPiUKICBmaWx0ZXIoIWlzLm5hKHN0dWR5X3llYXIpKSMgZG9udCBpbmNsdWRlIGFueSBOQQoKIyBQcmludCB0aGUgbmV3IEJDUyB0YWJsZQpwcmludCh1bmlxdWVfY291bnQpCnVuaXF1ZV9jb3VudF9kYXRhdGFibGUgPSBkYXRhdGFibGUodW5pcXVlX2NvdW50LCBvcHRpb25zID0gbGlzdCgpLCBjbGFzcyA9ICJkaXNwbGF5IikKdW5pcXVlX2NvdW50X2RhdGF0YWJsZQoKYGBgCgpQbG90CgpgYGB7ciwgd2FybmluZz1GQUxTRX0KIyBwbG90IHRoZSBmcmVxdWVuY3kgCmZpZ3VyZTEgPSBnZ3Bsb3QoZGF0YT11bmlxdWVfY291bnQsIGFlcyh4PXN0dWR5X3llYXIsIHk9RnJlcSwgZ3JvdXA9MSkpICsKICBnZW9tX2xpbmUoKSsKICBnZW9tX3BvaW50KCkrIAogIHRoZW1lX2J3KCkrCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoZmFjZT0iYm9sZCIsICBzaXplPTEwKSkgKyAKICB4bGFiKCJTdHVkeSBZZWFyIikgKyAKICB5bGFiKCJOdW1iZXIgb2YgRW5yb2xsZWQgR29sZGVucyIpICsKICBnZ3RpdGxlKCJTdHVkeSBlbnJvbGxtZW50IGJ5IHN0dWR5IHllYXIiKSArCiAgdGhlbWUoCiAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iQmxhY2siLCBzaXplPTE0LCBmYWNlPSJib2xkIikpKwogIHRoZW1lKHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChoanVzdD0wKSkKZmlndXJlMQoKIyBDb252ZXJ0IHRvIGFuIGludGVyYWN0aXZlIFBsb3RseSBwbG90CmludGVyYWN0aXZlX2ZpZzEgPC0gZ2dwbG90bHkoZmlndXJlMSkKCiMgUHJpbnQgdGhlIGludGVyYWN0aXZlIHBsb3QKaW50ZXJhY3RpdmVfZmlnMQpgYGAKCgoKIyMgQkNTIGJ5IHN0dWR5IHllYXIKYS4JUGVyIHN0dWR5IHllYXIsIGhvdyBtYW55IG9mIHRob3NlIGluZGl2aWR1YWwgZG9ncyBoYWQgYSBCQ1Mgb2YgMC0zCmIuCVBlciBzdHVkeSB5ZWFyIGhvdyBtYW55IG9mIHRob3NlIGluZGl2aWR1YWwgZG9ncyBoYWQgYSBCQ1Mgb2YgNC02IApjLglQZXIgc3R1ZHkgdWVhciBob3cgbWFueSBvZiB0aG9zZSBpbmRpdmlkdWFsIGRvZ3MgaGFkIGEgQkNTIG9mIDctOQoKYGBge3J9CkRpZXRfQ29tYmluZWREYXRhX0NsZWFuJHN0dWR5X3llYXIgPC0gZmFjdG9yKERpZXRfQ29tYmluZWREYXRhX0NsZWFuJHN0dWR5X3llYXIsIGxldmVscyA9IGMoIjAiLCAiMSIsICIyIiwgIjMiLCAiNCIsICI1IiwgIjYiLCAiNyIsICI4IiwgIjkiLCAiMTAiKSkKCmBgYAoKCmBgYHtyfQojIENyZWF0ZSBhIHRhYmxlIGZvciB0aGUgZnJlcXVlbmN5IG9mIGVhY2ggQm9keSBjb25kaXRpb24gc2NvcmUgcmFuZ2UgYnkgeWVhcgpCQ1NfdGFibGUgPSBEaWV0X0NvbWJpbmVkRGF0YV9DbGVhbiAlPiUKICBkaXN0aW5jdChzdHVkeV95ZWFyLCBiY3MsIGlkKSAlPiUKICBmaWx0ZXIoIWlzLm5hKHN0dWR5X3llYXIpLCAhaXMubmEoYmNzKSkgJT4lICMgRmlsdGVyIG91dCBOQSB2YWx1ZXMgaW4gY2FsZW5kYXJ5ZWFyIGFuZCBiY3MKICBtdXRhdGUoQkNTX1JhbmdlID0gY2FzZV93aGVuKAogICAgYmNzID49IDAgJiBiY3MgPD0gMyB+ICJMb3cgQkNTICgwLTMpIiwKICAgIGJjcyA+PSA0ICYgYmNzIDw9IDYgfiAiTm9ybWFsIEJDUyAoNC02KSIsCiAgICBiY3MgPj0gNyAmIGJjcyA8PSA5IH4gIkhpZ2ggQkNTICg3LTkpIiwKICAgIFRSVUUgfiAiVW5rbm93biIgIyBIYW5kbGUgYW55IG91dCBvZiByYW5nZSBvciB1bmV4cGVjdGVkIHZhbHVlcwogICkpICU+JQogIGdyb3VwX2J5KHN0dWR5X3llYXIsIEJDU19SYW5nZSkgJT4lCiAgc3VtbWFyaXplKEZyZXEgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICMgQ2FsY3VsYXRlIGZyZXF1ZW5jeQoKIyBQcmludCB0aGUgbmV3IEJDUyB0YWJsZQpwcmludChCQ1NfdGFibGUpCkJDU19kYXRhdGFibGUgPSBkYXRhdGFibGUoQkNTX3RhYmxlLCBvcHRpb25zID0gbGlzdCgpLCBjbGFzcyA9ICJkaXNwbGF5IikKQkNTX2RhdGF0YWJsZQoKIyBQbG90IHRoZSBmcmVxdWVuY3kgdXNpbmcgZ2dwbG90CmZpZ3VyZTIgPSBnZ3Bsb3QoZGF0YT1CQ1NfdGFibGUsIGFlcyh4PXN0dWR5X3llYXIsIHk9RnJlcSwgZ3JvdXA9QkNTX1JhbmdlLCBjb2xvcj1CQ1NfUmFuZ2UpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fcG9pbnQoKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoZmFjZT0iYm9sZCIsIHNpemU9MTApKSArCiAgeGxhYigiU3R1ZHkgWWVhciIpICsKICB5bGFiKCJOdW1iZXIgb2YgRG9ncyIpICsKICBnZ3RpdGxlKCJCQ1MgUmFuZ2UgYnkgWWVhciIpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGNvbG9yPSJCbGFjayIsIHNpemU9MTQsIGZhY2U9ImJvbGQiKSkgKwogIGxhYnMoY2FwdGlvbiA9ICJGaWd1cmUgMjogTnVtYmVyIG9mIERvZ3Mgd2l0aCBzcGVjaWZpYyBib2R5IGNvbmRpdGlvbiBzY29yZSByYW5nZXMgYnkgeWVhci4iKSArCiAgdGhlbWUocGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGhqdXN0PTApKQoKIyBDb252ZXJ0IHRvIGFuIGludGVyYWN0aXZlIFBsb3RseSBwbG90CmludGVyYWN0aXZlX2ZpZzIgPC0gZ2dwbG90bHkoZmlndXJlMikKCiMgUHJpbnQgdGhlIGludGVyYWN0aXZlIHBsb3QKaW50ZXJhY3RpdmVfZmlnMgpgYGAKCiMjIFByb2Nlc3NpbmcgYnkgc3R1ZHkgeWVhcgoKMi4JSG93IG1hbnkgaW5kaXZpZHVhbCBkb2dzIHdlcmUgaW4gZWFjaCBzdHVkeSB5ZWFyIHRoYXQgYXRlOgphLglNaW5pbWFsbHkgcHJvY2Vzc2VkCmIuCVByb2Nlc3NlZCAKYy4JVWx0cmEtcHJvY2Vzc2VkCgoKYGBge3J9CiMgQ3JlYXRlIGEgdGFibGUgZm9yIHRoZSBmcmVxdWVuY3kgb2YgZWFjaCBCb2R5IGNvbmRpdGlvbiBzY29yZSByYW5nZSBieSB5ZWFyCnByb2Nlc3NpbmdfdGFibGUgPSBEaWV0X0NvbWJpbmVkRGF0YV9DbGVhbiAlPiUKICBkaXN0aW5jdChzdHVkeV95ZWFyLCBwcm9jZXNzLmNhdGVnb3J5LCBpZCklPiUgICMgRmlsdGVyIG91dCBOQSB2YWx1ZXMgaW4gc3R1ZHlfeWVhciBhbmQgcHJvY2Vzcy5jYXRlZ29yeQogIGZpbHRlcighcHJvY2Vzcy5jYXRlZ29yeSAlaW4lIGMoIk4vQSIsICJVTksiLCAiVEJEIikpICU+JQogIGZpbHRlcighaXMubmEoc3R1ZHlfeWVhciksICFpcy5uYShwcm9jZXNzLmNhdGVnb3J5KSkgJT4lICMgRmlsdGVyIG91dCBOQSB2YWx1ZXMgaW4gY2FsZW5kYXJ5ZWFyIGFuZCBiY3MKICBncm91cF9ieShzdHVkeV95ZWFyLCBwcm9jZXNzLmNhdGVnb3J5KSAlPiUKICBzdW1tYXJpemUoRnJlcSA9IG4oKSwgLmdyb3VwcyA9ICdkcm9wJykgIyBDYWxjdWxhdGUgZnJlcXVlbmN5CgojIFByaW50IHRoZSBuZXcgQkNTIHRhYmxlCnByaW50KHByb2Nlc3NpbmdfdGFibGUpCnByb2Nlc3NpbmdfZGF0YXRhYmxlID0gZGF0YXRhYmxlKHByb2Nlc3NpbmdfdGFibGUsIG9wdGlvbnMgPSBsaXN0KCksIGNsYXNzID0gImRpc3BsYXkiKQpwcm9jZXNzaW5nX2RhdGF0YWJsZQoKIyBQbG90IHRoZSBmcmVxdWVuY3kgdXNpbmcgZ2dwbG90CmZpZ3VyZTMgPSBnZ3Bsb3QoZGF0YT1wcm9jZXNzaW5nX3RhYmxlLCBhZXMoeD1zdHVkeV95ZWFyLCB5PUZyZXEsIGdyb3VwPXByb2Nlc3MuY2F0ZWdvcnksIGNvbG9yPXByb2Nlc3MuY2F0ZWdvcnkpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fcG9pbnQoKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoZmFjZT0iYm9sZCIsIHNpemU9MTApKSArCiAgeGxhYigiU3R1ZHkgWWVhciIpICsKICB5bGFiKCJOdW1iZXIgb2YgRG9ncyIpICsKICBnZ3RpdGxlKCJQcm9jZXNzaW5nIENhdGVnb3JpemF0aW9uIGJ5IFN0dWR5IFllYXIiKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChjb2xvcj0iQmxhY2siLCBzaXplPTE0LCBmYWNlPSJib2xkIikpICsKICBsYWJzKGNhcHRpb24gPSAiRmlndXJlIDI6IE51bWJlciBvZiBEb2dzIHdpdGggc3BlY2lmaWMgYm9keSBjb25kaXRpb24gc2NvcmUgcmFuZ2VzIGJ5IHllYXIuIikgKwogIHRoZW1lKHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChoanVzdD0wKSkKCiMgQ29udmVydCB0byBhbiBpbnRlcmFjdGl2ZSBQbG90bHkgcGxvdAppbnRlcmFjdGl2ZV9maWczIDwtIGdncGxvdGx5KGZpZ3VyZTMpCgojIFByaW50IHRoZSBpbnRlcmFjdGl2ZSBwbG90CmludGVyYWN0aXZlX2ZpZzMKYGBgCgoKIyBDYXJkaW92YXNjdWxhcgpgYGB7cn0KI2xvYWQgZGF0YQpwcm9qZWN0LnBhdGggPSBoZXJlKCkKCkNvbWJpbmVkX0RhdGEubG9jYXRpb24gPSBoZXJlOjpoZXJlKCIxX0RhdGEiLCJSYXdfZGF0YSIsIkRpYWdub3NpcyIsImNhcmRpb3Zhc2N1bGFyLmNzdiIpCgojIGxvYWQgdGhlIGRhdGEgCgpjYXJkaW92YXNjdWxhciA9IHJlYWQuY3N2KENvbWJpbmVkX0RhdGEubG9jYXRpb24pCgojbWFrZSBhbGwgdGhlIG5hbWVzIGxvd2VyY2FzZQpuYW1lcyhjYXJkaW92YXNjdWxhcik8LXRvbG93ZXIobmFtZXMoY2FyZGlvdmFzY3VsYXIpKQoKYGBgCgpgYGB7cn0KI2FkZCB1bmlxdWUgSURzCmNhcmRpb3Zhc2N1bGFyJHVuaXF1ZV9pZCA9IHBhc3RlKGNhcmRpb3Zhc2N1bGFyJGlkLCAiXyIsIGNhcmRpb3Zhc2N1bGFyJHN0dWR5X3llYXIpCgojcmVsb2NhdGUgdG8gYmVnaW5pbmcKCmNhcmRpb3Zhc2N1bGFyID0gY2FyZGlvdmFzY3VsYXIgJT4lCgogIHJlbG9jYXRlKHVuaXF1ZV9pZCwgLmJlZm9yZSA9IGlkKQoKI0NoZWNrIAoKI2RwbHlyOjpnbGltcHNlKGNhcmRpb3Zhc2N1bGFyKQoKI3NraW1yOjpza2ltKGNhcmRpb3Zhc2N1bGFyKQoKYGBgCgpgYGB7cn0KCiMgQ2hlY2sgc3R1ZHkgSUQKCiMgQWNjb3JkaW5nIHRvIG91ciBkYXRhIHNvdXJjZSwgdGhlcmUgd2VyZSAzMDQ0IGRvZ3MgYXBhcnQgb2YgdGhlIHN0dWR5CgpVbmlxdWVfSWRlbnRpZmllcnMgPSB1bmlxdWUoY2FyZGlvdmFzY3VsYXIkaWQpCgpsZW5ndGgoVW5pcXVlX0lkZW50aWZpZXJzKQoKCiNjaGVjayBzdHVkeSBZZWFyCgojIGFjY29yZGluZyB0byBvdXIgZGF0YSBzb3VjZSwgZG9ncyBjYW4gYmUgYXBhcnQgb2YgdGhlIHN0dWR5IGZvciBhIG1heGltdW0gb2YgMTAgeWVhcnMsIHRoZSBic2FlbGluZSBpcyAwIGFuZCBzaG91bGQgYmUgaW4gd2hvbGUgbnVtYmVyCgoodW5pcXVlKGNhcmRpb3Zhc2N1bGFyJHN0dWR5X3llYXIpKQoKCmBgYAoKYGBge3J9CiNyZW5hbWUgYW55IGNvbHVtbgpjYXJkaW92YXNjdWxhciA9IGNhcmRpb3Zhc2N1bGFyICU+JSAKIHJlbmFtZSgiYW55X2NhcmRpbyIgPSAiYW55IikKYGBgCgojIyMjIEFkZCB0byBkaWV0IGRhdGEKYGBge3J9CiMgU2VsZWN0IG9ubHkgdGhlIHVuaXF1ZV9pZCBhbmQgYW55IGNvbHVtbnMgZnJvbSBjYXJkaW92YXNjdWxhcgpjYXJkaW92YXNjdWxhcl9yZWR1Y2VkIDwtIGNhcmRpb3Zhc2N1bGFyICU+JSAKICBzZWxlY3QodW5pcXVlX2lkLCBhbnlfY2FyZGlvKQpgYGAKCmBgYHtyfQojIEpvaW5pbmcgdGhlIHJlZHVjZWQgY2FyZGlvdmFzY3VsYXIgZGF0YSAKRGlldF9Db21iaW5lRGF0YV9VcGRhdGVkIDwtIERpZXRfQ29tYmluZWREYXRhX0NsZWFuICU+JQogIGxlZnRfam9pbihjYXJkaW92YXNjdWxhcl9yZWR1Y2VkLCBieSA9ICJ1bmlxdWVfaWQiKQpgYGAKCgojIEVuZG9jcmluZQpgYGB7cn0KI2xvYWQgZGF0YQpwcm9qZWN0LnBhdGggPSBoZXJlKCkKCkNvbWJpbmVkX0RhdGEubG9jYXRpb24gPSBoZXJlOjpoZXJlKCIxX0RhdGEiLCJSYXdfZGF0YSIsIkRpYWdub3NpcyIsImVuZG9jcmluZS5jc3YiKQoKIyBsb2FkIHRoZSBkYXRhIAoKZW5kb2NyaW5lID0gcmVhZC5jc3YoQ29tYmluZWRfRGF0YS5sb2NhdGlvbikKCiNtYWtlIGFsbCB0aGUgbmFtZXMgbG93ZXJjYXNlCm5hbWVzKGVuZG9jcmluZSk8LXRvbG93ZXIobmFtZXMoZW5kb2NyaW5lKSkKCmBgYAoKYGBge3J9CiNhZGQgdW5pcXVlIElEcwplbmRvY3JpbmUkdW5pcXVlX2lkID0gcGFzdGUoZW5kb2NyaW5lJGlkLCAiXyIsIGVuZG9jcmluZSRzdHVkeV95ZWFyKQoKI3JlbG9jYXRlIHRvIGJlZ2luaW5nCgplbmRvY3JpbmUgPSBlbmRvY3JpbmUgJT4lCgogIHJlbG9jYXRlKHVuaXF1ZV9pZCwgLmJlZm9yZSA9IGlkKQoKI0NoZWNrIAoKI2RwbHlyOjpnbGltcHNlKGVuZG9jcmluZSkKCiNza2ltcjo6c2tpbShlbmRvY3JpbmUpCgpgYGAKCmBgYHtyfQoKIyBDaGVjayBzdHVkeSBJRAoKIyBBY2NvcmRpbmcgdG8gb3VyIGRhdGEgc291cmNlLCB0aGVyZSB3ZXJlIDMwNDQgZG9ncyBhcGFydCBvZiB0aGUgc3R1ZHkKClVuaXF1ZV9JZGVudGlmaWVycyA9IHVuaXF1ZShlbmRvY3JpbmUkaWQpCgpsZW5ndGgoVW5pcXVlX0lkZW50aWZpZXJzKQoKCiNjaGVjayBzdHVkeSBZZWFyCgojIGFjY29yZGluZyB0byBvdXIgZGF0YSBzb3VjZSwgZG9ncyBjYW4gYmUgYXBhcnQgb2YgdGhlIHN0dWR5IGZvciBhIG1heGltdW0gb2YgMTAgeWVhcnMsIHRoZSBic2FlbGluZSBpcyAwIGFuZCBzaG91bGQgYmUgaW4gd2hvbGUgbnVtYmVyCgoodW5pcXVlKGVuZG9jcmluZSRzdHVkeV95ZWFyKSkKCgpgYGAKCmBgYHtyfQojcmVuYW1lIGFueSBjb2x1bW4KZW5kb2NyaW5lID0gZW5kb2NyaW5lICU+JSAKIHJlbmFtZSgiYW55X2VuZG9jcmluZSIgPSAiYW55IikKYGBgCgojIyMjIEFkZCB0byBkaWV0IGRhdGEKYGBge3J9CiMgU2VsZWN0IG9ubHkgdGhlIHVuaXF1ZV9pZCBhbmQgYW55IGNvbHVtbnMgZnJvbSBjYXJkaW92YXNjdWxhcgplbmRvY3JpbmVfcmVkdWNlZCA8LSBlbmRvY3JpbmUgJT4lIAogIHNlbGVjdCh1bmlxdWVfaWQsIGFueV9lbmRvY3JpbmUpCmBgYAoKYGBge3J9CiMgSm9pbmluZyB0aGUgcmVkdWNlZCBjYXJkaW92YXNjdWxhciBkYXRhIApEaWV0X0NvbWJpbmVEYXRhX1VwZGF0ZWQgPC0gRGlldF9Db21iaW5lRGF0YV9VcGRhdGVkICU+JQogIGxlZnRfam9pbihlbmRvY3JpbmVfcmVkdWNlZCwgYnkgPSAidW5pcXVlX2lkIikKYGBgCgoKIyBHYXN0cm9pbnRlc3RpbmFsCmBgYHtyfQojbG9hZCBkYXRhCnByb2plY3QucGF0aCA9IGhlcmUoKQoKRGF0YS5sb2NhdGlvbiA9IGhlcmU6OmhlcmUoIjFfRGF0YSIsIlJhd19kYXRhIiwiRGlhZ25vc2lzIiwiZ2FzdHJvaW50ZXN0aW5hbC5jc3YiKQoKIyBsb2FkIHRoZSBkYXRhIAoKZ2FzdHJvaW50ZXN0aW5hbCA9IHJlYWQuY3N2KERhdGEubG9jYXRpb24pCgojbWFrZSBhbGwgdGhlIG5hbWVzIGxvd2VyY2FzZQpuYW1lcyhnYXN0cm9pbnRlc3RpbmFsKTwtdG9sb3dlcihuYW1lcyhnYXN0cm9pbnRlc3RpbmFsKSkKCmBgYAoKYGBge3J9CiNhZGQgdW5pcXVlIElEcwpnYXN0cm9pbnRlc3RpbmFsJHVuaXF1ZV9pZCA9IHBhc3RlKGdhc3Ryb2ludGVzdGluYWwkaWQsICJfIiwgZ2FzdHJvaW50ZXN0aW5hbCRzdHVkeV95ZWFyKQoKI3JlbG9jYXRlIHRvIGJlZ2luaW5nCgpnYXN0cm9pbnRlc3RpbmFsID0gZ2FzdHJvaW50ZXN0aW5hbCAlPiUKCiAgcmVsb2NhdGUodW5pcXVlX2lkLCAuYmVmb3JlID0gaWQpCgojQ2hlY2sgCgojZHBseXI6OmdsaW1wc2UoZ2FzdHJvaW50ZXN0aW5hbCkKCiNza2ltcjo6c2tpbShnYXN0cm9pbnRlc3RpbmFsKQoKYGBgCgpgYGB7cn0KCiMgQ2hlY2sgc3R1ZHkgSUQKCiMgQWNjb3JkaW5nIHRvIG91ciBkYXRhIHNvdXJjZSwgdGhlcmUgd2VyZSAzMDQ0IGRvZ3MgYXBhcnQgb2YgdGhlIHN0dWR5CgpVbmlxdWVfSWRlbnRpZmllcnMgPSB1bmlxdWUoZ2FzdHJvaW50ZXN0aW5hbCRpZCkKCmxlbmd0aChVbmlxdWVfSWRlbnRpZmllcnMpCgoKI2NoZWNrIHN0dWR5IFllYXIKCiMgYWNjb3JkaW5nIHRvIG91ciBkYXRhIHNvdWNlLCBkb2dzIGNhbiBiZSBhcGFydCBvZiB0aGUgc3R1ZHkgZm9yIGEgbWF4aW11bSBvZiAxMCB5ZWFycywgdGhlIGJzYWVsaW5lIGlzIDAgYW5kIHNob3VsZCBiZSBpbiB3aG9sZSBudW1iZXIKCih1bmlxdWUoZ2FzdHJvaW50ZXN0aW5hbCRzdHVkeV95ZWFyKSkKCgpgYGAKCmBgYHtyfQojcmVuYW1lIGFueSBjb2x1bW4KZ2FzdHJvaW50ZXN0aW5hbCA9IGdhc3Ryb2ludGVzdGluYWwgJT4lIAogcmVuYW1lKCJhbnlfZ2FzdHJvaW50ZXN0aW5hbCIgPSAiYW55IikKYGBgCgojIyMjIEFkZCB0byBkaWV0IGRhdGEKYGBge3J9CiMgU2VsZWN0IG9ubHkgdGhlIHVuaXF1ZV9pZCBhbmQgYW55IGNvbHVtbnMgZnJvbSBjYXJkaW92YXNjdWxhcgpnYXN0cm9pbnRlc3RpbmFsX3JlZHVjZWQgPC0gZ2FzdHJvaW50ZXN0aW5hbCAlPiUgCiAgc2VsZWN0KHVuaXF1ZV9pZCwgYW55X2dhc3Ryb2ludGVzdGluYWwpCmBgYAoKYGBge3J9CiMgSm9pbmluZyB0aGUgcmVkdWNlZCBjYXJkaW92YXNjdWxhciBkYXRhIApEaWV0X0NvbWJpbmVEYXRhX1VwZGF0ZWQgPC0gRGlldF9Db21iaW5lRGF0YV9VcGRhdGVkICU+JQogIGxlZnRfam9pbihnYXN0cm9pbnRlc3RpbmFsX3JlZHVjZWQsIGJ5ID0gInVuaXF1ZV9pZCIpCmBgYAoKCiMgSGVtYXRvbG9naWMKYGBge3J9CiNsb2FkIGRhdGEKcHJvamVjdC5wYXRoID0gaGVyZSgpCgpEYXRhLmxvY2F0aW9uID0gaGVyZTo6aGVyZSgiMV9EYXRhIiwiUmF3X2RhdGEiLCJEaWFnbm9zaXMiLCJoZW1hdG9sb2dpYy5jc3YiKQoKIyBsb2FkIHRoZSBkYXRhIAoKaGVtYXRvbG9naWMgPSByZWFkLmNzdihEYXRhLmxvY2F0aW9uKQoKI21ha2UgYWxsIHRoZSBuYW1lcyBsb3dlcmNhc2UKbmFtZXMoaGVtYXRvbG9naWMpPC10b2xvd2VyKG5hbWVzKGhlbWF0b2xvZ2ljKSkKCmBgYAoKYGBge3J9CiNhZGQgdW5pcXVlIElEcwpoZW1hdG9sb2dpYyR1bmlxdWVfaWQgPSBwYXN0ZShoZW1hdG9sb2dpYyRpZCwgIl8iLCBoZW1hdG9sb2dpYyRzdHVkeV95ZWFyKQoKI3JlbG9jYXRlIHRvIGJlZ2luaW5nCgpoZW1hdG9sb2dpYyA9IGhlbWF0b2xvZ2ljICU+JQoKICByZWxvY2F0ZSh1bmlxdWVfaWQsIC5iZWZvcmUgPSBpZCkKCiNDaGVjayAKCiNkcGx5cjo6Z2xpbXBzZShoZW1hdG9sb2dpYykKCiNza2ltcjo6c2tpbShoZW1hdG9sb2dpYykKCmBgYAoKYGBge3J9CgojIENoZWNrIHN0dWR5IElECgojIEFjY29yZGluZyB0byBvdXIgZGF0YSBzb3VyY2UsIHRoZXJlIHdlcmUgMzA0NCBkb2dzIGFwYXJ0IG9mIHRoZSBzdHVkeQoKVW5pcXVlX0lkZW50aWZpZXJzID0gdW5pcXVlKGhlbWF0b2xvZ2ljJGlkKQoKbGVuZ3RoKFVuaXF1ZV9JZGVudGlmaWVycykKCgojY2hlY2sgc3R1ZHkgWWVhcgoKIyBhY2NvcmRpbmcgdG8gb3VyIGRhdGEgc291Y2UsIGRvZ3MgY2FuIGJlIGFwYXJ0IG9mIHRoZSBzdHVkeSBmb3IgYSBtYXhpbXVtIG9mIDEwIHllYXJzLCB0aGUgYnNhZWxpbmUgaXMgMCBhbmQgc2hvdWxkIGJlIGluIHdob2xlIG51bWJlcgoKKHVuaXF1ZShoZW1hdG9sb2dpYyRzdHVkeV95ZWFyKSkKCgpgYGAKCmBgYHtyfQojcmVuYW1lIGFueSBjb2x1bW4KaGVtYXRvbG9naWMgPSBoZW1hdG9sb2dpYyAlPiUgCiByZW5hbWUoImFueV9oZW1hdG9sb2dpYyIgPSAiYW55IikKYGBgCgojIyMjIEFkZCB0byBkaWV0IGRhdGEKYGBge3J9CiMgU2VsZWN0IG9ubHkgdGhlIHVuaXF1ZV9pZCBhbmQgYW55IGNvbHVtbnMgZnJvbSBjYXJkaW92YXNjdWxhcgpoZW1hdG9sb2dpY19yZWR1Y2VkIDwtIGhlbWF0b2xvZ2ljICU+JSAKICBzZWxlY3QodW5pcXVlX2lkLCBhbnlfaGVtYXRvbG9naWMpCmBgYAoKYGBge3J9CiMgSm9pbmluZyB0aGUgcmVkdWNlZCBjYXJkaW92YXNjdWxhciBkYXRhIApEaWV0X0NvbWJpbmVEYXRhX1VwZGF0ZWQgPC0gRGlldF9Db21iaW5lRGF0YV9VcGRhdGVkICU+JQogIGxlZnRfam9pbihoZW1hdG9sb2dpY19yZWR1Y2VkLCBieSA9ICJ1bmlxdWVfaWQiKQpgYGAKCiMgbXVzY3Vsb3NrZWxldGFsCmBgYHtyfQojbG9hZCBkYXRhCnByb2plY3QucGF0aCA9IGhlcmUoKQoKRGF0YS5sb2NhdGlvbiA9IGhlcmU6OmhlcmUoIjFfRGF0YSIsIlJhd19kYXRhIiwiRGlhZ25vc2lzIiwibXVzY3Vsb3NrZWxldGFsLmNzdiIpCgojIGxvYWQgdGhlIGRhdGEgCgptdXNjdWxvc2tlbGV0YWwgPSByZWFkLmNzdihEYXRhLmxvY2F0aW9uKQoKI21ha2UgYWxsIHRoZSBuYW1lcyBsb3dlcmNhc2UKbmFtZXMobXVzY3Vsb3NrZWxldGFsKTwtdG9sb3dlcihuYW1lcyhtdXNjdWxvc2tlbGV0YWwpKQoKYGBgCgpgYGB7cn0KI2FkZCB1bmlxdWUgSURzCm11c2N1bG9za2VsZXRhbCR1bmlxdWVfaWQgPSBwYXN0ZShtdXNjdWxvc2tlbGV0YWwkaWQsICJfIiwgbXVzY3Vsb3NrZWxldGFsJHN0dWR5X3llYXIpCgojcmVsb2NhdGUgdG8gYmVnaW5pbmcKCm11c2N1bG9za2VsZXRhbCA9IG11c2N1bG9za2VsZXRhbCAlPiUKCiAgcmVsb2NhdGUodW5pcXVlX2lkLCAuYmVmb3JlID0gaWQpCgojQ2hlY2sgCgojZHBseXI6OmdsaW1wc2UobXVzY3Vsb3NrZWxldGFsKQoKI3NraW1yOjpza2ltKG11c2N1bG9za2VsZXRhbCkKCmBgYAoKYGBge3J9CgojIENoZWNrIHN0dWR5IElECgojIEFjY29yZGluZyB0byBvdXIgZGF0YSBzb3VyY2UsIHRoZXJlIHdlcmUgMzA0NCBkb2dzIGFwYXJ0IG9mIHRoZSBzdHVkeQoKVW5pcXVlX0lkZW50aWZpZXJzID0gdW5pcXVlKG11c2N1bG9za2VsZXRhbCRpZCkKCmxlbmd0aChVbmlxdWVfSWRlbnRpZmllcnMpCgoKI2NoZWNrIHN0dWR5IFllYXIKCiMgYWNjb3JkaW5nIHRvIG91ciBkYXRhIHNvdWNlLCBkb2dzIGNhbiBiZSBhcGFydCBvZiB0aGUgc3R1ZHkgZm9yIGEgbWF4aW11bSBvZiAxMCB5ZWFycywgdGhlIGJzYWVsaW5lIGlzIDAgYW5kIHNob3VsZCBiZSBpbiB3aG9sZSBudW1iZXIKCih1bmlxdWUobXVzY3Vsb3NrZWxldGFsJHN0dWR5X3llYXIpKQoKCmBgYAoKYGBge3J9CiNyZW5hbWUgYW55IGNvbHVtbgptdXNjdWxvc2tlbGV0YWwgPSBtdXNjdWxvc2tlbGV0YWwgJT4lIAogcmVuYW1lKCJhbnlfbXVzY3Vsb3NrZWxldGFsIiA9ICJhbnkiKQpgYGAKCiMjIyMgQWRkIHRvIGRpZXQgZGF0YQpgYGB7cn0KIyBTZWxlY3Qgb25seSB0aGUgdW5pcXVlX2lkIGFuZCBhbnkgY29sdW1ucyBmcm9tIGNhcmRpb3Zhc2N1bGFyCm11c2N1bG9za2VsZXRhbF9yZWR1Y2VkIDwtIG11c2N1bG9za2VsZXRhbCAlPiUgCiAgc2VsZWN0KHVuaXF1ZV9pZCwgYW55X211c2N1bG9za2VsZXRhbCkKYGBgCgpgYGB7cn0KIyBKb2luaW5nIHRoZSByZWR1Y2VkIGNhcmRpb3Zhc2N1bGFyIGRhdGEgCkRpZXRfQ29tYmluZURhdGFfVXBkYXRlZCA8LSBEaWV0X0NvbWJpbmVEYXRhX1VwZGF0ZWQgJT4lCiAgbGVmdF9qb2luKG11c2N1bG9za2VsZXRhbF9yZWR1Y2VkLCBieSA9ICJ1bmlxdWVfaWQiKQpgYGAKCgojIE5lcnZvdXMKYGBge3J9CiNsb2FkIGRhdGEKcHJvamVjdC5wYXRoID0gaGVyZSgpCgpEYXRhLmxvY2F0aW9uID0gaGVyZTo6aGVyZSgiMV9EYXRhIiwiUmF3X2RhdGEiLCJEaWFnbm9zaXMiLCJuZXJ2b3VzLmNzdiIpCgojIGxvYWQgdGhlIGRhdGEgCgpuZXJ2b3VzID0gcmVhZC5jc3YoRGF0YS5sb2NhdGlvbikKCiNtYWtlIGFsbCB0aGUgbmFtZXMgbG93ZXJjYXNlCm5hbWVzKG5lcnZvdXMpPC10b2xvd2VyKG5hbWVzKG5lcnZvdXMpKQoKYGBgCgpgYGB7cn0KI2FkZCB1bmlxdWUgSURzCm5lcnZvdXMkdW5pcXVlX2lkID0gcGFzdGUobmVydm91cyRpZCwgIl8iLCBuZXJ2b3VzJHN0dWR5X3llYXIpCgojcmVsb2NhdGUgdG8gYmVnaW5pbmcKCm5lcnZvdXMgPSBuZXJ2b3VzICU+JQoKICByZWxvY2F0ZSh1bmlxdWVfaWQsIC5iZWZvcmUgPSBpZCkKCiNDaGVjayAKCiNkcGx5cjo6Z2xpbXBzZShuZXJ2b3VzKQoKI3NraW1yOjpza2ltKG5lcnZvdXMpCgpgYGAKCmBgYHtyfQoKIyBDaGVjayBzdHVkeSBJRAoKIyBBY2NvcmRpbmcgdG8gb3VyIGRhdGEgc291cmNlLCB0aGVyZSB3ZXJlIDMwNDQgZG9ncyBhcGFydCBvZiB0aGUgc3R1ZHkKClVuaXF1ZV9JZGVudGlmaWVycyA9IHVuaXF1ZShuZXJ2b3VzJGlkKQoKbGVuZ3RoKFVuaXF1ZV9JZGVudGlmaWVycykKCgojY2hlY2sgc3R1ZHkgWWVhcgoKIyBhY2NvcmRpbmcgdG8gb3VyIGRhdGEgc291Y2UsIGRvZ3MgY2FuIGJlIGFwYXJ0IG9mIHRoZSBzdHVkeSBmb3IgYSBtYXhpbXVtIG9mIDEwIHllYXJzLCB0aGUgYnNhZWxpbmUgaXMgMCBhbmQgc2hvdWxkIGJlIGluIHdob2xlIG51bWJlcgoKKHVuaXF1ZShuZXJ2b3VzJHN0dWR5X3llYXIpKQoKCmBgYAoKYGBge3J9CiNyZW5hbWUgYW55IGNvbHVtbgpuZXJ2b3VzID0gbmVydm91cyAlPiUgCiByZW5hbWUoImFueV9uZXJ2b3VzIiA9ICJhbnkiKQpgYGAKCiMjIyMgQWRkIHRvIGRpZXQgZGF0YQpgYGB7cn0KIyBTZWxlY3Qgb25seSB0aGUgdW5pcXVlX2lkIGFuZCBhbnkgY29sdW1ucyBmcm9tIGNhcmRpb3Zhc2N1bGFyCm5lcnZvdXNfcmVkdWNlZCA8LSBuZXJ2b3VzICU+JSAKICBzZWxlY3QodW5pcXVlX2lkLCBhbnlfbmVydm91cykKYGBgCgpgYGB7cn0KIyBKb2luaW5nIHRoZSByZWR1Y2VkIGNhcmRpb3Zhc2N1bGFyIGRhdGEgCkRpZXRfQ29tYmluZURhdGFfVXBkYXRlZCA8LSBEaWV0X0NvbWJpbmVEYXRhX1VwZGF0ZWQgJT4lCiAgbGVmdF9qb2luKG5lcnZvdXNfcmVkdWNlZCwgYnkgPSAidW5pcXVlX2lkIikKYGBgCgoKIyBVcmluYXJ5CmBgYHtyfQojbG9hZCBkYXRhCnByb2plY3QucGF0aCA9IGhlcmUoKQoKRGF0YS5sb2NhdGlvbiA9IGhlcmU6OmhlcmUoIjFfRGF0YSIsIlJhd19kYXRhIiwiRGlhZ25vc2lzIiwidXJpbmFyeS5jc3YiKQoKIyBsb2FkIHRoZSBkYXRhIAoKdXJpbmFyeSA9IHJlYWQuY3N2KERhdGEubG9jYXRpb24pCgojbWFrZSBhbGwgdGhlIG5hbWVzIGxvd2VyY2FzZQpuYW1lcyh1cmluYXJ5KTwtdG9sb3dlcihuYW1lcyh1cmluYXJ5KSkKCmBgYAoKYGBge3J9CiNhZGQgdW5pcXVlIElEcwp1cmluYXJ5JHVuaXF1ZV9pZCA9IHBhc3RlKHVyaW5hcnkkaWQsICJfIiwgdXJpbmFyeSRzdHVkeV95ZWFyKQoKI3JlbG9jYXRlIHRvIGJlZ2luaW5nCgp1cmluYXJ5ID0gdXJpbmFyeSAlPiUKCiAgcmVsb2NhdGUodW5pcXVlX2lkLCAuYmVmb3JlID0gaWQpCgojQ2hlY2sgCgojZHBseXI6OmdsaW1wc2UodXJpbmFyeSkKCiNza2ltcjo6c2tpbSh1cmluYXJ5KQoKYGBgCgpgYGB7cn0KCiMgQ2hlY2sgc3R1ZHkgSUQKCiMgQWNjb3JkaW5nIHRvIG91ciBkYXRhIHNvdXJjZSwgdGhlcmUgd2VyZSAzMDQ0IGRvZ3MgYXBhcnQgb2YgdGhlIHN0dWR5CgpVbmlxdWVfSWRlbnRpZmllcnMgPSB1bmlxdWUodXJpbmFyeSRpZCkKCmxlbmd0aChVbmlxdWVfSWRlbnRpZmllcnMpCgoKI2NoZWNrIHN0dWR5IFllYXIKCiMgYWNjb3JkaW5nIHRvIG91ciBkYXRhIHNvdWNlLCBkb2dzIGNhbiBiZSBhcGFydCBvZiB0aGUgc3R1ZHkgZm9yIGEgbWF4aW11bSBvZiAxMCB5ZWFycywgdGhlIGJzYWVsaW5lIGlzIDAgYW5kIHNob3VsZCBiZSBpbiB3aG9sZSBudW1iZXIKCih1bmlxdWUodXJpbmFyeSRzdHVkeV95ZWFyKSkKCgpgYGAKCmBgYHtyfQojcmVuYW1lIGFueSBjb2x1bW4KdXJpbmFyeSA9IHVyaW5hcnkgJT4lIAogcmVuYW1lKCJhbnlfdXJpbmFyeSIgPSAiYW55IikKYGBgCgojIyMjIEFkZCB0byBkaWV0IGRhdGEKYGBge3J9CiMgU2VsZWN0IG9ubHkgdGhlIHVuaXF1ZV9pZCBhbmQgYW55IGNvbHVtbnMgZnJvbSBjYXJkaW92YXNjdWxhcgp1cmluYXJ5X3JlZHVjZWQgPC0gdXJpbmFyeSAlPiUgCiAgc2VsZWN0KHVuaXF1ZV9pZCwgYW55X3VyaW5hcnkpCmBgYAoKYGBge3J9CiMgSm9pbmluZyB0aGUgcmVkdWNlZCBjYXJkaW92YXNjdWxhciBkYXRhIApEaWV0X0NvbWJpbmVEYXRhX1VwZGF0ZWQgPC0gRGlldF9Db21iaW5lRGF0YV9VcGRhdGVkICU+JQogIGxlZnRfam9pbih1cmluYXJ5X3JlZHVjZWQsIGJ5ID0gInVuaXF1ZV9pZCIpCmBgYAoKCiMjIGFkZCBjb2x1bW4gdG8gZGV0ZXJtaW5lIGlmIGEgZG9nIGhhcyBhbnkgbWFqb3IgZGlhZ25vc2lzIApgYGB7cn0KRGlldF9Db21iaW5lRGF0YV9VcGRhdGVkIDwtIERpZXRfQ29tYmluZURhdGFfVXBkYXRlZCAlPiUKICByb3d3aXNlKCkgJT4lICAjIEFwcGx5IHRoZSBvcGVyYXRpb24gcm93IGJ5IHJvdwogIG11dGF0ZShhbnlfbWFqb3JfZGlhZ25vc2lzID0gaWZfZWxzZShhbnlfY2FyZGlvID09IDEgfCBhbnlfZW5kb2NyaW5lID09IDEgfCBhbnlfZ2FzdHJvaW50ZXN0aW5hbCA9PSAxIHwgYW55X211c2N1bG9za2VsZXRhbCA9PSAxIHwgYW55X25lcnZvdXMgPT0gMSB8IGFueV91cmluYXJ5ID09IDEgfCBhbnlfaGVtYXRvbG9naWMgPT0gMSwgMSwgMCkpICU+JQogIHVuZ3JvdXAoKSAgIyBSZW1vdmUgdGhlIHJvd3dpc2UgZ3JvdXBpbmcKYGBgCgoKIyBtaW5vciBkaWFnbm9zaXMKCiMgRXllCmBgYHtyfQojbG9hZCBkYXRhCnByb2plY3QucGF0aCA9IGhlcmUoKQoKRGF0YS5sb2NhdGlvbiA9IGhlcmU6OmhlcmUoIjFfRGF0YSIsIlJhd19kYXRhIiwiRGlhZ25vc2lzIiwiZXllLmNzdiIpCgojIGxvYWQgdGhlIGRhdGEgCgpleWUgPSByZWFkLmNzdihEYXRhLmxvY2F0aW9uKQoKI21ha2UgYWxsIHRoZSBuYW1lcyBsb3dlcmNhc2UKbmFtZXMoZXllKTwtdG9sb3dlcihuYW1lcyhleWUpKQoKYGBgCgpgYGB7cn0KI2FkZCB1bmlxdWUgSURzCmV5ZSR1bmlxdWVfaWQgPSBwYXN0ZShleWUkaWQsICJfIiwgZXllJHN0dWR5X3llYXIpCgojcmVsb2NhdGUgdG8gYmVnaW5pbmcKCmV5ZSA9IGV5ZSAlPiUKCiAgcmVsb2NhdGUodW5pcXVlX2lkLCAuYmVmb3JlID0gaWQpCgojQ2hlY2sgCgojZHBseXI6OmdsaW1wc2UoZXllKQoKI3NraW1yOjpza2ltKGV5ZSkKCmBgYAoKYGBge3J9CgojIENoZWNrIHN0dWR5IElECgojIEFjY29yZGluZyB0byBvdXIgZGF0YSBzb3VyY2UsIHRoZXJlIHdlcmUgMzA0NCBkb2dzIGFwYXJ0IG9mIHRoZSBzdHVkeQoKVW5pcXVlX0lkZW50aWZpZXJzID0gdW5pcXVlKGV5ZSRpZCkKCmxlbmd0aChVbmlxdWVfSWRlbnRpZmllcnMpCgoKI2NoZWNrIHN0dWR5IFllYXIKCiMgYWNjb3JkaW5nIHRvIG91ciBkYXRhIHNvdWNlLCBkb2dzIGNhbiBiZSBhcGFydCBvZiB0aGUgc3R1ZHkgZm9yIGEgbWF4aW11bSBvZiAxMCB5ZWFycywgdGhlIGJzYWVsaW5lIGlzIDAgYW5kIHNob3VsZCBiZSBpbiB3aG9sZSBudW1iZXIKCih1bmlxdWUoZXllJHN0dWR5X3llYXIpKQoKCmBgYAoKYGBge3J9CiNyZW5hbWUgYW55IGNvbHVtbgpleWUgPSBleWUgJT4lIAogcmVuYW1lKCJhbnlfZXllIiA9ICJhbnkiKQpgYGAKCiMjIyMgQWRkIHRvIGRpZXQgZGF0YQpgYGB7cn0KIyBTZWxlY3Qgb25seSB0aGUgdW5pcXVlX2lkIGFuZCBhbnkgY29sdW1ucyBmcm9tIGNhcmRpb3Zhc2N1bGFyCmV5ZV9yZWR1Y2VkIDwtIGV5ZSAlPiUgCiAgc2VsZWN0KHVuaXF1ZV9pZCwgYW55X2V5ZSkKYGBgCgpgYGB7cn0KIyBKb2luaW5nIHRoZSByZWR1Y2VkIGNhcmRpb3Zhc2N1bGFyIGRhdGEgCkRpZXRfQ29tYmluZURhdGFfVXBkYXRlZCA8LSBEaWV0X0NvbWJpbmVEYXRhX1VwZGF0ZWQgJT4lCiAgbGVmdF9qb2luKGV5ZV9yZWR1Y2VkLCBieSA9ICJ1bmlxdWVfaWQiKQpgYGAKCgojIEluZmVjdGlvbgpgYGB7cn0KI2xvYWQgZGF0YQpwcm9qZWN0LnBhdGggPSBoZXJlKCkKCkRhdGEubG9jYXRpb24gPSBoZXJlOjpoZXJlKCIxX0RhdGEiLCJSYXdfZGF0YSIsIkRpYWdub3NpcyIsImluZmVjdGlvdXMuY3N2IikKCiMgbG9hZCB0aGUgZGF0YSAKCmluZmVjdGlvdXMgPSByZWFkLmNzdihEYXRhLmxvY2F0aW9uKQoKI21ha2UgYWxsIHRoZSBuYW1lcyBsb3dlcmNhc2UKbmFtZXMoaW5mZWN0aW91cyk8LXRvbG93ZXIobmFtZXMoaW5mZWN0aW91cykpCgpgYGAKCmBgYHtyfQojYWRkIHVuaXF1ZSBJRHMKaW5mZWN0aW91cyR1bmlxdWVfaWQgPSBwYXN0ZShpbmZlY3Rpb3VzJGlkLCAiXyIsIGluZmVjdGlvdXMkc3R1ZHlfeWVhcikKCiNyZWxvY2F0ZSB0byBiZWdpbmluZwoKaW5mZWN0aW91cyA9IGluZmVjdGlvdXMgJT4lCgogIHJlbG9jYXRlKHVuaXF1ZV9pZCwgLmJlZm9yZSA9IGlkKQoKI0NoZWNrIAoKI2RwbHlyOjpnbGltcHNlKGluZmVjdGlvdXMpCgojc2tpbXI6OnNraW0oaW5mZWN0aW91cykKCmBgYAoKYGBge3J9CgojIENoZWNrIHN0dWR5IElECgojIEFjY29yZGluZyB0byBvdXIgZGF0YSBzb3VyY2UsIHRoZXJlIHdlcmUgMzA0NCBkb2dzIGFwYXJ0IG9mIHRoZSBzdHVkeQoKVW5pcXVlX0lkZW50aWZpZXJzID0gdW5pcXVlKGluZmVjdGlvdXMkaWQpCgpsZW5ndGgoVW5pcXVlX0lkZW50aWZpZXJzKQoKCiNjaGVjayBzdHVkeSBZZWFyCgojIGFjY29yZGluZyB0byBvdXIgZGF0YSBzb3VjZSwgZG9ncyBjYW4gYmUgYXBhcnQgb2YgdGhlIHN0dWR5IGZvciBhIG1heGltdW0gb2YgMTAgeWVhcnMsIHRoZSBic2FlbGluZSBpcyAwIGFuZCBzaG91bGQgYmUgaW4gd2hvbGUgbnVtYmVyCgoodW5pcXVlKGluZmVjdGlvdXMkc3R1ZHlfeWVhcikpCgoKYGBgCgpgYGB7cn0KI3JlbmFtZSBhbnkgY29sdW1uCmluZmVjdGlvdXMgPSBpbmZlY3Rpb3VzICU+JSAKIHJlbmFtZSgiYW55X2luZmVjdGlvdXMiID0gImFueSIpCmBgYAoKIyMjIyBBZGQgdG8gZGlldCBkYXRhCmBgYHtyfQojIFNlbGVjdCBvbmx5IHRoZSB1bmlxdWVfaWQgYW5kIGFueSBjb2x1bW5zIGZyb20gY2FyZGlvdmFzY3VsYXIKaW5mZWN0aW91c19yZWR1Y2VkIDwtIGluZmVjdGlvdXMgJT4lIAogIHNlbGVjdCh1bmlxdWVfaWQsIGFueV9pbmZlY3Rpb3VzKQpgYGAKCmBgYHtyfQojIEpvaW5pbmcgdGhlIHJlZHVjZWQgY2FyZGlvdmFzY3VsYXIgZGF0YSAKRGlldF9Db21iaW5lRGF0YV9VcGRhdGVkIDwtIERpZXRfQ29tYmluZURhdGFfVXBkYXRlZCAlPiUKICBsZWZ0X2pvaW4oaW5mZWN0aW91c19yZWR1Y2VkLCBieSA9ICJ1bmlxdWVfaWQiKQpgYGAKCgojIHNraW4KYGBge3J9CiNsb2FkIGRhdGEKcHJvamVjdC5wYXRoID0gaGVyZSgpCgpEYXRhLmxvY2F0aW9uID0gaGVyZTo6aGVyZSgiMV9EYXRhIiwiUmF3X2RhdGEiLCJEaWFnbm9zaXMiLCJza2luLmNzdiIpCgojIGxvYWQgdGhlIGRhdGEgCgpza2luID0gcmVhZC5jc3YoRGF0YS5sb2NhdGlvbikKCiNtYWtlIGFsbCB0aGUgbmFtZXMgbG93ZXJjYXNlCm5hbWVzKHNraW4pPC10b2xvd2VyKG5hbWVzKHNraW4pKQoKYGBgCgpgYGB7cn0KI2FkZCB1bmlxdWUgSURzCnNraW4kdW5pcXVlX2lkID0gcGFzdGUoc2tpbiRpZCwgIl8iLCBza2luJHN0dWR5X3llYXIpCgojcmVsb2NhdGUgdG8gYmVnaW5pbmcKCnNraW4gPSBza2luICU+JQoKICByZWxvY2F0ZSh1bmlxdWVfaWQsIC5iZWZvcmUgPSBpZCkKCiNDaGVjayAKCiNkcGx5cjo6Z2xpbXBzZShza2luKQoKI3NraW1yOjpza2ltKHNraW4pCgpgYGAKCmBgYHtyfQoKIyBDaGVjayBzdHVkeSBJRAoKIyBBY2NvcmRpbmcgdG8gb3VyIGRhdGEgc291cmNlLCB0aGVyZSB3ZXJlIDMwNDQgZG9ncyBhcGFydCBvZiB0aGUgc3R1ZHkKClVuaXF1ZV9JZGVudGlmaWVycyA9IHVuaXF1ZShza2luJGlkKQoKbGVuZ3RoKFVuaXF1ZV9JZGVudGlmaWVycykKCgojY2hlY2sgc3R1ZHkgWWVhcgoKIyBhY2NvcmRpbmcgdG8gb3VyIGRhdGEgc291Y2UsIGRvZ3MgY2FuIGJlIGFwYXJ0IG9mIHRoZSBzdHVkeSBmb3IgYSBtYXhpbXVtIG9mIDEwIHllYXJzLCB0aGUgYnNhZWxpbmUgaXMgMCBhbmQgc2hvdWxkIGJlIGluIHdob2xlIG51bWJlcgoKKHVuaXF1ZShza2luJHN0dWR5X3llYXIpKQoKCmBgYAoKYGBge3J9CiNyZW5hbWUgYW55IGNvbHVtbgpza2luID0gc2tpbiAlPiUgCiByZW5hbWUoImFueV9za2luIiA9ICJhbnkiKQpgYGAKCiMjIyMgQWRkIHRvIGRpZXQgZGF0YQpgYGB7cn0KIyBTZWxlY3Qgb25seSB0aGUgdW5pcXVlX2lkIGFuZCBhbnkgY29sdW1ucyBmcm9tIGNhcmRpb3Zhc2N1bGFyCnNraW5fcmVkdWNlZCA8LSBza2luICU+JSAKICBzZWxlY3QodW5pcXVlX2lkLCBhbnlfc2tpbikKYGBgCgpgYGB7cn0KIyBKb2luaW5nIHRoZSByZWR1Y2VkIGNhcmRpb3Zhc2N1bGFyIGRhdGEgCkRpZXRfQ29tYmluZURhdGFfVXBkYXRlZCA8LSBEaWV0X0NvbWJpbmVEYXRhX1VwZGF0ZWQgJT4lCiAgbGVmdF9qb2luKHNraW5fcmVkdWNlZCwgYnkgPSAidW5pcXVlX2lkIikKYGBgCgoKCiMgcmVwcm9kdWN0aXZlCmBgYHtyfQojbG9hZCBkYXRhCnByb2plY3QucGF0aCA9IGhlcmUoKQoKRGF0YS5sb2NhdGlvbiA9IGhlcmU6OmhlcmUoIjFfRGF0YSIsIlJhd19kYXRhIiwiRGlhZ25vc2lzIiwicmVwcm9kdWN0aXZlLmNzdiIpCgojIGxvYWQgdGhlIGRhdGEgCgpyZXByb2R1Y3RpdmUgPSByZWFkLmNzdihEYXRhLmxvY2F0aW9uKQoKI21ha2UgYWxsIHRoZSBuYW1lcyBsb3dlcmNhc2UKbmFtZXMocmVwcm9kdWN0aXZlKTwtdG9sb3dlcihuYW1lcyhyZXByb2R1Y3RpdmUpKQoKYGBgCgpgYGB7cn0KI2FkZCB1bmlxdWUgSURzCnJlcHJvZHVjdGl2ZSR1bmlxdWVfaWQgPSBwYXN0ZShyZXByb2R1Y3RpdmUkaWQsICJfIiwgcmVwcm9kdWN0aXZlJHN0dWR5X3llYXIpCgojcmVsb2NhdGUgdG8gYmVnaW5pbmcKCnJlcHJvZHVjdGl2ZSA9IHJlcHJvZHVjdGl2ZSAlPiUKCiAgcmVsb2NhdGUodW5pcXVlX2lkLCAuYmVmb3JlID0gaWQpCgojQ2hlY2sgCgojZHBseXI6OmdsaW1wc2UocmVwcm9kdWN0aXZlKQoKI3NraW1yOjpza2ltKHJlcHJvZHVjdGl2ZSkKCmBgYAoKYGBge3J9CgojIENoZWNrIHN0dWR5IElECgojIEFjY29yZGluZyB0byBvdXIgZGF0YSBzb3VyY2UsIHRoZXJlIHdlcmUgMzA0NCBkb2dzIGFwYXJ0IG9mIHRoZSBzdHVkeQoKVW5pcXVlX0lkZW50aWZpZXJzID0gdW5pcXVlKHJlcHJvZHVjdGl2ZSRpZCkKCmxlbmd0aChVbmlxdWVfSWRlbnRpZmllcnMpCgoKI2NoZWNrIHN0dWR5IFllYXIKCiMgYWNjb3JkaW5nIHRvIG91ciBkYXRhIHNvdWNlLCBkb2dzIGNhbiBiZSBhcGFydCBvZiB0aGUgc3R1ZHkgZm9yIGEgbWF4aW11bSBvZiAxMCB5ZWFycywgdGhlIGJzYWVsaW5lIGlzIDAgYW5kIHNob3VsZCBiZSBpbiB3aG9sZSBudW1iZXIKCih1bmlxdWUocmVwcm9kdWN0aXZlJHN0dWR5X3llYXIpKQoKCmBgYAoKYGBge3J9CiNyZW5hbWUgYW55IGNvbHVtbgpyZXByb2R1Y3RpdmUgPSByZXByb2R1Y3RpdmUgJT4lIAogcmVuYW1lKCJhbnlfcmVwcm9kdWN0aXZlIiA9ICJhbnkiKQpgYGAKCiMjIyMgQWRkIHRvIGRpZXQgZGF0YQpgYGB7cn0KIyBTZWxlY3Qgb25seSB0aGUgdW5pcXVlX2lkIGFuZCBhbnkgY29sdW1ucyBmcm9tIGNhcmRpb3Zhc2N1bGFyCnJlcHJvZHVjdGl2ZV9yZWR1Y2VkIDwtIHJlcHJvZHVjdGl2ZSAlPiUgCiAgc2VsZWN0KHVuaXF1ZV9pZCwgYW55X3JlcHJvZHVjdGl2ZSkKYGBgCgpgYGB7cn0KIyBKb2luaW5nIHRoZSByZWR1Y2VkIGNhcmRpb3Zhc2N1bGFyIGRhdGEgCkRpZXRfQ29tYmluZURhdGFfVXBkYXRlZCA8LSBEaWV0X0NvbWJpbmVEYXRhX1VwZGF0ZWQgJT4lCiAgbGVmdF9qb2luKHJlcHJvZHVjdGl2ZV9yZWR1Y2VkLCBieSA9ICJ1bmlxdWVfaWQiKQpgYGAKCgoKIyBkZW50YWwKYGBge3J9CiNsb2FkIGRhdGEKcHJvamVjdC5wYXRoID0gaGVyZSgpCgpEYXRhLmxvY2F0aW9uID0gaGVyZTo6aGVyZSgiMV9EYXRhIiwiUmF3X2RhdGEiLCJEaWFnbm9zaXMiLCJkZW50YWwuY3N2IikKCiMgbG9hZCB0aGUgZGF0YSAKCmRlbnRhbCA9IHJlYWQuY3N2KERhdGEubG9jYXRpb24pCgojbWFrZSBhbGwgdGhlIG5hbWVzIGxvd2VyY2FzZQpuYW1lcyhkZW50YWwpPC10b2xvd2VyKG5hbWVzKGRlbnRhbCkpCgpgYGAKCmBgYHtyfQojYWRkIHVuaXF1ZSBJRHMKZGVudGFsJHVuaXF1ZV9pZCA9IHBhc3RlKGRlbnRhbCRpZCwgIl8iLCBkZW50YWwkc3R1ZHlfeWVhcikKCiNyZWxvY2F0ZSB0byBiZWdpbmluZwoKZGVudGFsID0gZGVudGFsICU+JQoKICByZWxvY2F0ZSh1bmlxdWVfaWQsIC5iZWZvcmUgPSBpZCkKCiNDaGVjayAKCiNkcGx5cjo6Z2xpbXBzZShkZW50YWwpCgojc2tpbXI6OnNraW0oZGVudGFsKQoKYGBgCgpgYGB7cn0KCiMgQ2hlY2sgc3R1ZHkgSUQKCiMgQWNjb3JkaW5nIHRvIG91ciBkYXRhIHNvdXJjZSwgdGhlcmUgd2VyZSAzMDQ0IGRvZ3MgYXBhcnQgb2YgdGhlIHN0dWR5CgpVbmlxdWVfSWRlbnRpZmllcnMgPSB1bmlxdWUoZGVudGFsJGlkKQoKbGVuZ3RoKFVuaXF1ZV9JZGVudGlmaWVycykKCgojY2hlY2sgc3R1ZHkgWWVhcgoKIyBhY2NvcmRpbmcgdG8gb3VyIGRhdGEgc291Y2UsIGRvZ3MgY2FuIGJlIGFwYXJ0IG9mIHRoZSBzdHVkeSBmb3IgYSBtYXhpbXVtIG9mIDEwIHllYXJzLCB0aGUgYnNhZWxpbmUgaXMgMCBhbmQgc2hvdWxkIGJlIGluIHdob2xlIG51bWJlcgoKKHVuaXF1ZShkZW50YWwkc3R1ZHlfeWVhcikpCgoKYGBgCgpgYGB7cn0KI3JlbmFtZSBhbnkgY29sdW1uCmRlbnRhbCA9IGRlbnRhbCAlPiUgCiByZW5hbWUoImFueV9kZW50YWwiID0gImFueSIpCmBgYAoKIyMjIyBBZGQgdG8gZGlldCBkYXRhCmBgYHtyfQojIFNlbGVjdCBvbmx5IHRoZSB1bmlxdWVfaWQgYW5kIGFueSBjb2x1bW5zIGZyb20gY2FyZGlvdmFzY3VsYXIKZGVudGFsX3JlZHVjZWQgPC0gZGVudGFsICU+JSAKICBzZWxlY3QodW5pcXVlX2lkLCBhbnlfZGVudGFsKQpgYGAKCmBgYHtyfQojIEpvaW5pbmcgdGhlIHJlZHVjZWQgY2FyZGlvdmFzY3VsYXIgZGF0YSAKRGlldF9Db21iaW5lRGF0YV9VcGRhdGVkIDwtIERpZXRfQ29tYmluZURhdGFfVXBkYXRlZCAlPiUKICBsZWZ0X2pvaW4oZGVudGFsX3JlZHVjZWQsIGJ5ID0gInVuaXF1ZV9pZCIpCmBgYAoKCgoKIyBlYXIgbm9zZSB0aHJvYXQKYGBge3J9CiNsb2FkIGRhdGEKcHJvamVjdC5wYXRoID0gaGVyZSgpCgpEYXRhLmxvY2F0aW9uID0gaGVyZTo6aGVyZSgiMV9EYXRhIiwiUmF3X2RhdGEiLCJEaWFnbm9zaXMiLCJlYXJfbm9zZV90aHJvYXQuY3N2IikKCiMgbG9hZCB0aGUgZGF0YSAKCmVhcl9ub3NlX3Rocm9hdCA9IHJlYWQuY3N2KERhdGEubG9jYXRpb24pCgojbWFrZSBhbGwgdGhlIG5hbWVzIGxvd2VyY2FzZQpuYW1lcyhlYXJfbm9zZV90aHJvYXQpPC10b2xvd2VyKG5hbWVzKGVhcl9ub3NlX3Rocm9hdCkpCgpgYGAKCmBgYHtyfQojYWRkIHVuaXF1ZSBJRHMKZWFyX25vc2VfdGhyb2F0JHVuaXF1ZV9pZCA9IHBhc3RlKGVhcl9ub3NlX3Rocm9hdCRpZCwgIl8iLCBlYXJfbm9zZV90aHJvYXQkc3R1ZHlfeWVhcikKCiNyZWxvY2F0ZSB0byBiZWdpbmluZwoKZWFyX25vc2VfdGhyb2F0ID0gZWFyX25vc2VfdGhyb2F0ICU+JQoKICByZWxvY2F0ZSh1bmlxdWVfaWQsIC5iZWZvcmUgPSBpZCkKCiNDaGVjayAKCiNkcGx5cjo6Z2xpbXBzZShlYXJfbm9zZV90aHJvYXQpCgojc2tpbXI6OnNraW0oZWFyX25vc2VfdGhyb2F0KQoKYGBgCgpgYGB7cn0KCiMgQ2hlY2sgc3R1ZHkgSUQKCiMgQWNjb3JkaW5nIHRvIG91ciBkYXRhIHNvdXJjZSwgdGhlcmUgd2VyZSAzMDQ0IGRvZ3MgYXBhcnQgb2YgdGhlIHN0dWR5CgpVbmlxdWVfSWRlbnRpZmllcnMgPSB1bmlxdWUoZWFyX25vc2VfdGhyb2F0JGlkKQoKbGVuZ3RoKFVuaXF1ZV9JZGVudGlmaWVycykKCgojY2hlY2sgc3R1ZHkgWWVhcgoKIyBhY2NvcmRpbmcgdG8gb3VyIGRhdGEgc291Y2UsIGRvZ3MgY2FuIGJlIGFwYXJ0IG9mIHRoZSBzdHVkeSBmb3IgYSBtYXhpbXVtIG9mIDEwIHllYXJzLCB0aGUgYnNhZWxpbmUgaXMgMCBhbmQgc2hvdWxkIGJlIGluIHdob2xlIG51bWJlcgoKKHVuaXF1ZShlYXJfbm9zZV90aHJvYXQkc3R1ZHlfeWVhcikpCgoKYGBgCgpgYGB7cn0KI3JlbmFtZSBhbnkgY29sdW1uCmVhcl9ub3NlX3Rocm9hdCA9IGVhcl9ub3NlX3Rocm9hdCAlPiUgCiByZW5hbWUoImFueV9lYXJfbm9zZV90aHJvYXQiID0gImFueSIpCmBgYAoKIyMjIyBBZGQgdG8gZGlldCBkYXRhCmBgYHtyfQojIFNlbGVjdCBvbmx5IHRoZSB1bmlxdWVfaWQgYW5kIGFueSBjb2x1bW5zIGZyb20gY2FyZGlvdmFzY3VsYXIKZWFyX25vc2VfdGhyb2F0X3JlZHVjZWQgPC0gZWFyX25vc2VfdGhyb2F0ICU+JSAKICBzZWxlY3QodW5pcXVlX2lkLCBhbnlfZWFyX25vc2VfdGhyb2F0KQpgYGAKCmBgYHtyfQojIEpvaW5pbmcgdGhlIHJlZHVjZWQgY2FyZGlvdmFzY3VsYXIgZGF0YSAKRGlldF9Db21iaW5lRGF0YV9VcGRhdGVkIDwtIERpZXRfQ29tYmluZURhdGFfVXBkYXRlZCAlPiUKICBsZWZ0X2pvaW4oZWFyX25vc2VfdGhyb2F0X3JlZHVjZWQsIGJ5ID0gInVuaXF1ZV9pZCIpCmBgYAoKCiMjIGFkZCBjb2x1bW4gdG8gZGV0ZXJtaW5lIGlmIGEgZG9nIGhhcyBhbnkgbWlub3IgZGlhZ25vc2lzIApgYGB7cn0KRGlldF9Db21iaW5lRGF0YV9VcGRhdGVkID0gRGlldF9Db21iaW5lRGF0YV9VcGRhdGVkICU+JQogIHJvd3dpc2UoKSAlPiUgICMgQXBwbHkgdGhlIG9wZXJhdGlvbiByb3cgYnkgcm93CiAgbXV0YXRlKGFueV9taW5vcl9kaWFnbm9zaXMgPSBpZl9lbHNlKGFueV9leWUgPT0gMSB8IGFueV9kZW50YWwgPT0gMSB8IGFueV9lYXJfbm9zZV90aHJvYXQgPT0gMSB8IGFueV9yZXByb2R1Y3RpdmUgPT0gMSB8IGFueV9pbmZlY3Rpb3VzID09IDEgfCBhbnlfc2tpbiA9PSAxLCAxLCAwKSkgJT4lCiAgdW5ncm91cCgpICAjIFJlbW92ZSB0aGUgcm93d2lzZSBncm91cGluZwpgYGAKCgojIyBhZGQgY29sdW1uIHRvIGRldGVybWluZSBpZiBhIGRvZyBoYXMgYW55IGRpYWdub3NpcyAKYGBge3J9CkRpZXRfQ29tYmluZURhdGFfVXBkYXRlZCA9IERpZXRfQ29tYmluZURhdGFfVXBkYXRlZCAlPiUKICByb3d3aXNlKCkgJT4lICAjIEFwcGx5IHRoZSBvcGVyYXRpb24gcm93IGJ5IHJvdwogIG11dGF0ZShhbnlfZGlhZ25vc2lzID0gaWZfZWxzZShhbnlfY2FyZGlvID09IDEgfCBhbnlfZW5kb2NyaW5lID09IDEgfCBhbnlfZ2FzdHJvaW50ZXN0aW5hbCA9PSAxIHwgYW55X211c2N1bG9za2VsZXRhbCA9PSAxIHwgYW55X25lcnZvdXMgPT0gMSB8IGFueV9uZXJ2b3VzID09IDEgfCBhbnlfdXJpbmFyeSA9PSAxIHwgYW55X2V5ZSA9PSAxIHwgYW55X2Vhcl9ub3NlX3Rocm9hdCA9PSAxIHwgYW55X2luZmVjdGlvdXMgPT0gMSB8IGFueV9za2luID09IDEgfCBhbnlfdXJpbmFyeSA9PTEsIDEsIDApKSAlPiUKICB1bmdyb3VwKCkgICMgUmVtb3ZlIHRoZSByb3d3aXNlIGdyb3VwaW5nCmBgYAoKIyMgTWFqb3IgbWlub3IgYW5kIGRpYWdub3NpcwoKYGBge3J9CiMgU3VtbWFyaXplIGRhdGEgdG8gZ2V0IGNvdW50cyBvZiBkaWFnbm9zaXMgdnMuIG5vIGRpYWdub3NpcyBieSBzdHVkeV95ZWFyCiNtaW5vcl9kaWFnbm9zaXNfc3VtbWFyeSA8LSBEaWV0X0NvbWJpbmVEYXRhX1VwZGF0ZWQgJT4lCiMgICBmaWx0ZXIoIWlzLm5hKGFueV9taW5vcl9kaWFnbm9zaXMpKSAlPiUKIyAgZ3JvdXBfYnkoc3R1ZHlfeWVhciwgYW55X21pbm9yX2RpYWdub3NpcykgJT4lCiMgIHN1bW1hcml6ZShGcmVxdWVuY3kgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JQojICBtdXRhdGUoYW55X21pbm9yX2RpYWdub3NpcyA9IGZhY3RvcihhbnlfbWlub3JfZGlhZ25vc2lzLCBsZXZlbHMgPSBjKDAsIDEpLCBsYWJlbHMgPSBjKCJObyBEaWFnbm9zaXMiLCAiRGlhZ25vc2lzIikpKQojbWlub3JfZGlhZ25vc2lzX3N1bW1hcnkKCgojIFVwZGF0ZSB0aGUgdGFibGUgdG8gaW5jbHVkZSBCQ1MgcmFuZ2VzCm1pbm9yX2RpYWdub3Npc19zdW1tYXJ5IDwtIERpZXRfQ29tYmluZURhdGFfVXBkYXRlZCAlPiUKICBmaWx0ZXIoIWlzLm5hKGFueV9taW5vcl9kaWFnbm9zaXMpKSAlPiUKICBmaWx0ZXIoIWlzLm5hKGJjcykpICU+JQogIG11dGF0ZShCQ1NfUmFuZ2UgPSBjYXNlX3doZW4oCiAgICBiY3MgPj0gMCAmIGJjcyA8PSAzIH4gIkxvdyBCQ1MgKDAtMykiLAogICAgYmNzID49IDQgJiBiY3MgPD0gNiB+ICJOb3JtYWwgQkNTICg0LTYpIiwKICAgIGJjcyA+PSA3ICYgYmNzIDw9IDkgfiAiSGlnaCBCQ1MgKDctOSkiLAogICAgVFJVRSB+ICJVbmtub3duIiAKICApKSAlPiUKICBncm91cF9ieShzdHVkeV95ZWFyLCBCQ1NfUmFuZ2UsIGFueV9taW5vcl9kaWFnbm9zaXMpICU+JQogIHN1bW1hcml6ZShGcmVxdWVuY3kgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JQogIG11dGF0ZShhbnlfbWlub3JfZGlhZ25vc2lzID0gZmFjdG9yKGFueV9taW5vcl9kaWFnbm9zaXMsIGxldmVscyA9IGMoMCwgMSksIGxhYmVscyA9IGMoIk5vIERpYWdub3NpcyIsICJEaWFnbm9zaXMiKSkpCgojIFByaW50IHRoZSB1cGRhdGVkIHN1bW1hcnkKcHJpbnQobWlub3JfZGlhZ25vc2lzX3N1bW1hcnkpCgptaW5vcl9kaWFnbm9zaXNfc3VtbWFyeV9kYXRhdGFibGUgPSBkYXRhdGFibGUobWlub3JfZGlhZ25vc2lzX3N1bW1hcnksIG9wdGlvbnMgPSBsaXN0KCksIGNsYXNzID0gImRpc3BsYXkiKQptaW5vcl9kaWFnbm9zaXNfc3VtbWFyeV9kYXRhdGFibGUKYGBgCgoKCgoKYGBge3J9CiMgU3VtbWFyaXplIGRhdGEgdG8gZ2V0IGNvdW50cyBvZiBkaWFnbm9zaXMgdnMuIG5vIGRpYWdub3NpcyBieSBzdHVkeV95ZWFyCiNtYWpvcl9kaWFnbm9zaXNfc3VtbWFyeSA8LSBEaWV0X0NvbWJpbmVEYXRhX1VwZGF0ZWQgJT4lCiMgICBmaWx0ZXIoIWlzLm5hKGFueV9tYWpvcl9kaWFnbm9zaXMpKSAlPiUKIyAgZ3JvdXBfYnkoc3R1ZHlfeWVhciwgYW55X21ham9yX2RpYWdub3NpcykgJT4lCiMgIHN1bW1hcml6ZShGcmVxdWVuY3kgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JQojICBtdXRhdGUoYW55X21ham9yX2RpYWdub3NpcyA9IGZhY3RvcihhbnlfbWFqb3JfZGlhZ25vc2lzLCBsZXZlbHMgPSBjKDAsIDEpLCBsYWJlbHMgPSBjKCJObyBEaWFnbm9zaXMiLCAiRGlhZ25vc2lzIikpKQojbWFqb3JfZGlhZ25vc2lzX3N1bW1hcnkKCgojIFVwZGF0ZSB0aGUgdGFibGUgdG8gaW5jbHVkZSBCQ1MgcmFuZ2VzCm1ham9yX2RpYWdub3Npc19zdW1tYXJ5IDwtIERpZXRfQ29tYmluZURhdGFfVXBkYXRlZCAlPiUKICBmaWx0ZXIoIWlzLm5hKGFueV9tYWpvcl9kaWFnbm9zaXMpKSAlPiUKICBmaWx0ZXIoIWlzLm5hKGJjcykpICU+JQogIG11dGF0ZShCQ1NfUmFuZ2UgPSBjYXNlX3doZW4oCiAgICBiY3MgPj0gMCAmIGJjcyA8PSAzIH4gIkxvdyBCQ1MgKDAtMykiLAogICAgYmNzID49IDQgJiBiY3MgPD0gNiB+ICJOb3JtYWwgQkNTICg0LTYpIiwKICAgIGJjcyA+PSA3ICYgYmNzIDw9IDkgfiAiSGlnaCBCQ1MgKDctOSkiLAogICAgVFJVRSB+ICJVbmtub3duIiAKICApKSAlPiUKICBncm91cF9ieShzdHVkeV95ZWFyLCBCQ1NfUmFuZ2UsIGFueV9tYWpvcl9kaWFnbm9zaXMpICU+JQogIHN1bW1hcml6ZShGcmVxdWVuY3kgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JQogIG11dGF0ZShhbnlfbWFqb3JfZGlhZ25vc2lzID0gZmFjdG9yKGFueV9tYWpvcl9kaWFnbm9zaXMsIGxldmVscyA9IGMoMCwgMSksIGxhYmVscyA9IGMoIk5vIERpYWdub3NpcyIsICJEaWFnbm9zaXMiKSkpCgojIFByaW50IHRoZSB1cGRhdGVkIHN1bW1hcnkKcHJpbnQobWFqb3JfZGlhZ25vc2lzX3N1bW1hcnkpCgptYWpvcl9kaWFnbm9zaXNfc3VtbWFyeV9kYXRhdGFibGUgPSBkYXRhdGFibGUobWFqb3JfZGlhZ25vc2lzX3N1bW1hcnksIG9wdGlvbnMgPSBsaXN0KCksIGNsYXNzID0gImRpc3BsYXkiKQptYWpvcl9kaWFnbm9zaXNfc3VtbWFyeV9kYXRhdGFibGUKYGBgCgpgYGB7cn0KIyBBbnkgZGlhZ25vc2lzCgojIFVwZGF0ZSB0aGUgdGFibGUgdG8gaW5jbHVkZSBCQ1MgcmFuZ2VzCmRpYWdub3Npc19zdW1tYXJ5IDwtIERpZXRfQ29tYmluZURhdGFfVXBkYXRlZCAlPiUKICBmaWx0ZXIoIWlzLm5hKGFueV9kaWFnbm9zaXMpKSAlPiUKICBmaWx0ZXIoIWlzLm5hKGJjcykpICU+JQogIG11dGF0ZShCQ1NfUmFuZ2UgPSBjYXNlX3doZW4oCiAgICBiY3MgPj0gMCAmIGJjcyA8PSAzIH4gIkxvdyBCQ1MgKDAtMykiLAogICAgYmNzID49IDQgJiBiY3MgPD0gNiB+ICJOb3JtYWwgQkNTICg0LTYpIiwKICAgIGJjcyA+PSA3ICYgYmNzIDw9IDkgfiAiSGlnaCBCQ1MgKDctOSkiLAogICAgVFJVRSB+ICJVbmtub3duIiAKICApKSAlPiUKICBncm91cF9ieShzdHVkeV95ZWFyLCBCQ1NfUmFuZ2UsIGFueV9kaWFnbm9zaXMpICU+JQogIHN1bW1hcml6ZShGcmVxdWVuY3kgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JQogIG11dGF0ZShhbnlfZGlhZ25vc2lzID0gZmFjdG9yKGFueV9kaWFnbm9zaXMsIGxldmVscyA9IGMoMCwgMSksIGxhYmVscyA9IGMoIk5vIERpYWdub3NpcyIsICJEaWFnbm9zaXMiKSkpCgojIFByaW50IHRoZSB1cGRhdGVkIHN1bW1hcnkKcHJpbnQoZGlhZ25vc2lzX3N1bW1hcnkpCgpkaWFnbm9zaXNfc3VtbWFyeV9kYXRhdGFibGUgPSBkYXRhdGFibGUoZGlhZ25vc2lzX3N1bW1hcnksIG9wdGlvbnMgPSBsaXN0KCksIGNsYXNzID0gImRpc3BsYXkiKQpkaWFnbm9zaXNfc3VtbWFyeV9kYXRhdGFibGUKYGBgCgoKCmBgYHtyfQojIENyZWF0ZSB0aGUgYmFyIHBsb3QKbWFqb3JfcGxvdCA8LSBnZ3Bsb3QobWFqb3JfZGlhZ25vc2lzX3N1bW1hcnksIGFlcyh4ID0gc3R1ZHlfeWVhciwgeSA9IEZyZXF1ZW5jeSwgZmlsbCA9IGFueV9tYWpvcl9kaWFnbm9zaXMsIGdyb3VwID0gKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsgZmFjZXRfd3JhcCh+QkNTX1JhbmdlKSsgIyBVc2UgZG9kZ2UgcG9zaXRpb24gdG8gcGxhY2UgYmFycyBzaWRlIGJ5IHNpZGUKICBsYWJzKHRpdGxlID0gIkZyZXF1ZW5jeSBvZiAgTWFqb3IgRGlhZ25vc2lzIGJ5IFN0dWR5IFllYXIiLAogICAgICAgeCA9ICJTdHVkeSBZZWFyIiwKICAgICAgIHkgPSAiRnJlcXVlbmN5IiwKICAgICAgIGZpbGwgPSAiRGlhZ25vc2lzIFN0YXR1cyIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICAjIFJvdGF0ZSB4LWF4aXMgbGFiZWxzIGZvciByZWFkYWJpbGl0eQoKIyBEaXNwbGF5IHRoZSBwbG90CnByaW50KG1ham9yX3Bsb3QpCgojIENvbnZlcnQgdG8gYW4gaW50ZXJhY3RpdmUgUGxvdGx5IHBsb3QKaW50ZXJhY3RpdmVfZmlnNCA8LSBnZ3Bsb3RseShtYWpvcl9wbG90KQoKaW50ZXJhY3RpdmVfZmlnNCA8LSBpbnRlcmFjdGl2ZV9maWc0ICU+JQogIGxheW91dChsZWdlbmQgPSBsaXN0KG9yaWVudGF0aW9uID0gImgiLCB4ID0gMC41LCB4YW5jaG9yID0gImNlbnRlciIsIHkgPSAxLjEpKQoKIyBQcmludCB0aGUgaW50ZXJhY3RpdmUgcGxvdAppbnRlcmFjdGl2ZV9maWc0CmBgYAoKYGBge3J9CiMgQ3JlYXRlIHRoZSBiYXIgcGxvdAptaW5vcl9wbG90IDwtIGdncGxvdChtaW5vcl9kaWFnbm9zaXNfc3VtbWFyeSwgYWVzKHggPSBzdHVkeV95ZWFyLCB5ID0gRnJlcXVlbmN5LCBmaWxsID0gYW55X21pbm9yX2RpYWdub3NpcykpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiKSArIGZhY2V0X3dyYXAofkJDU19SYW5nZSkgKyAgIyBVc2UgZG9kZ2UgcG9zaXRpb24gdG8gcGxhY2UgYmFycyBzaWRlIGJ5IHNpZGUKICBsYWJzKHRpdGxlID0gIkZyZXF1ZW5jeSBvZiBNaW5vciBEaWFnbm9zaXMgYnkgU3R1ZHkgWWVhciAiLAogICAgICAgeCA9ICJTdHVkeSBZZWFyIiwKICAgICAgIHkgPSAiRnJlcXVlbmN5IiwKICAgICAgIGZpbGwgPSAiRGlhZ25vc2lzIFN0YXR1cyIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSAgIyBSb3RhdGUgeC1heGlzIGxhYmVscyBmb3IgcmVhZGFiaWxpdHkKCiMgRGlzcGxheSB0aGUgcGxvdApwcmludChtaW5vcl9wbG90KQoKIyBDb252ZXJ0IHRvIGFuIGludGVyYWN0aXZlIFBsb3RseSBwbG90CmludGVyYWN0aXZlX2ZpZzUgPC0gZ2dwbG90bHkobWlub3JfcGxvdCkKCgppbnRlcmFjdGl2ZV9maWc1IDwtIGludGVyYWN0aXZlX2ZpZzUgJT4lCiAgbGF5b3V0KGxlZ2VuZCA9IGxpc3Qob3JpZW50YXRpb24gPSAiaCIsIHggPSAwLjUsIHhhbmNob3IgPSAiY2VudGVyIiwgeSA9IDEuMSkpCgojIFByaW50IHRoZSBpbnRlcmFjdGl2ZSBwbG90CmludGVyYWN0aXZlX2ZpZzUKCmBgYAoKYGBge3J9CiMgQ3JlYXRlIHRoZSBiYXIgcGxvdApkaWFnbm9zaXNfcGxvdCA8LSBnZ3Bsb3QoZGlhZ25vc2lzX3N1bW1hcnksIGFlcyh4ID0gc3R1ZHlfeWVhciwgeSA9IEZyZXF1ZW5jeSwgZmlsbCA9IGFueV9kaWFnbm9zaXMsIGdyb3VwID0gKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsgZmFjZXRfd3JhcCh+QkNTX1JhbmdlKSsgIyBVc2UgZG9kZ2UgcG9zaXRpb24gdG8gcGxhY2UgYmFycyBzaWRlIGJ5IHNpZGUKICBsYWJzKHRpdGxlID0gIkZyZXF1ZW5jeSBvZiBEaWFnbm9zaXMgYnkgU3R1ZHkgWWVhciIsCiAgICAgICB4ID0gIlN0dWR5IFllYXIiLAogICAgICAgeSA9ICJGcmVxdWVuY3kiLAogICAgICAgZmlsbCA9ICJEaWFnbm9zaXMgU3RhdHVzIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgICMgUm90YXRlIHgtYXhpcyBsYWJlbHMgZm9yIHJlYWRhYmlsaXR5CgojIERpc3BsYXkgdGhlIHBsb3QKcHJpbnQobWFqb3JfcGxvdCkKCiMgQ29udmVydCB0byBhbiBpbnRlcmFjdGl2ZSBQbG90bHkgcGxvdAppbnRlcmFjdGl2ZV9maWc2IDwtIGdncGxvdGx5KGRpYWdub3Npc19wbG90KQoKaW50ZXJhY3RpdmVfZmlnNiA8LSBpbnRlcmFjdGl2ZV9maWc2ICU+JQogIGxheW91dChsZWdlbmQgPSBsaXN0KG9yaWVudGF0aW9uID0gImgiLCB4ID0gMC41LCB4YW5jaG9yID0gImNlbnRlciIsIHkgPSAxLjEpKQoKIyBQcmludCB0aGUgaW50ZXJhY3RpdmUgcGxvdAppbnRlcmFjdGl2ZV9maWc2CmBgYAoKIyBGaWx0ZXIgdGhlIGRvZ3MgYmFzZWQgb24gQWdlLCBiY3MsIGFuZCBkaWFnbm9zaXMgCgoKRGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgZG9ncyB0aGF0IGhhdmUgYSBCQ1Mgb2YgNCw1LCBvciA2IGJldHdlZW4gdGhlIGFnZSBvZiAwLTMsIDQtNiAsIDcrIHRoYXQgYXJlIGdlbmVyYWxseSBoZWFsdGh5IG9uIGEgbWluaW1hbGx5IHByb2Nlc3NlZCBkaWV0IApgYGB7cn0KIyBGaWx0ZXIgRGlldF9EYXRhX0NsZWFuIGZvciBhZ2UgYW5kIEJDUyBjb25kaXRpb25zCiNlbGlnaWJsZV95b3VuZ19kb2dzIDwtIERpZXRfRGF0YV9DbGVhbiAlPiUKIyAgZmlsdGVyKHZpc2l0LmFnZSA8IDMsIEJDU19udW1lcmljIDwgNykKI2xlbmd0aCh1bmlxdWUoZWxpZ2libGVfeW91bmdfZG9ncyRpZCkpCgojIEZpbHRlciBEaWV0X0RhdGFfQ2xlYW4gZm9yIGFnZSB1bmRlciAzIHllYXJzIGFuZCBCQ1MgYmVsb3cgNwojZWxpZ2libGVfeW91bmdfZG9ncyA8LSBEaWV0X0NvbWJpbmVEYXRhX1VwZGF0ZWQgJT4lCiMjICBmaWx0ZXIodmlzaXQuYWdlIDwgMywgYmNzICVpbiUgYyg0LDUsNikpICU+JQojICBkaXN0aW5jdCgpCiNsZW5ndGgodW5pcXVlKGVsaWdpYmxlX3lvdW5nX2RvZ3MkaWQpKQoKZWxpZ2libGVfeW91bmdfZG9ncyA8LSBEaWV0X0NvbWJpbmVEYXRhX1VwZGF0ZWQgJT4lCiAgZmlsdGVyKHZpc2l0LmFnZSA8PSAzLCAgICAgICAgICAgICAgICAjIEFnZSB1bmRlciAzIHllYXJzCiAgICAgICAgIGJjcyAlaW4lIGMoNCwgNSwgNiksICAgICAgICAgICMgQkNTIG9mIDQsIDUsIG9yIDYKICAgICAgICAgYW55X21ham9yX2RpYWdub3NpcyA9PSAwLCAgICAgIyBFeGNsdWRlIGRvZ3Mgd2l0aCBhbnkgbWFqb3IgZGlhZ25vc2lzCiAgICAgICAgIHByb2Nlc3MuY2F0ZWdvcnkgPT0gIk1pbmltYWxseSBQcm9jZXNzZWQiKSAlPiUKICBkaXN0aW5jdCgpICAjIFJlbW92ZSBkdXBsaWNhdGVzCmxlbmd0aCh1bmlxdWUoZWxpZ2libGVfeW91bmdfZG9ncyRpZCkpCgplbGlnaWJsZV9taWRfZG9ncyA8LSBEaWV0X0NvbWJpbmVEYXRhX1VwZGF0ZWQgJT4lCiAgZmlsdGVyKHZpc2l0LmFnZSA+MyAmIHZpc2l0LmFnZSA8PSA2LCAgICAgICAgICAgICAgICAjIGJldHdlZW4gNC02CiAgICAgICAgIGJjcyAlaW4lIGMoNCwgNSwgNiksICAgICAgICAgICMgQkNTIG9mIDQsIDUsIG9yIDYKICAgICAgICAgYW55X21ham9yX2RpYWdub3NpcyA9PSAwLCAgICAgIyBFeGNsdWRlIGRvZ3Mgd2l0aCBhbnkgbWFqb3IgZGlhZ25vc2lzCiAgICAgICAgIHByb2Nlc3MuY2F0ZWdvcnkgPT0gIk1pbmltYWxseSBQcm9jZXNzZWQiKSAlPiUKICBkaXN0aW5jdCgpICAjIFJlbW92ZSBkdXBsaWNhdGVzCmxlbmd0aCh1bmlxdWUoZWxpZ2libGVfbWlkX2RvZ3MkaWQpKQoKZWxpZ2libGVfb2xkX2RvZ3MgPC0gRGlldF9Db21iaW5lRGF0YV9VcGRhdGVkICU+JQogIGZpbHRlcih2aXNpdC5hZ2UgPiA3LCAgICAgICAgICAgICAgICAjIG92ZXIgNwogICAgICAgICBiY3MgJWluJSBjKDQsIDUsIDYpLCAgICAgICAgICAjIEJDUyBvZiA0LCA1LCBvciA2CiAgICAgICAgIGFueV9tYWpvcl9kaWFnbm9zaXMgPT0gMCwgICAgICMgRXhjbHVkZSBkb2dzIHdpdGggYW55IG1ham9yIGRpYWdub3NpcwogICAgICAgICBwcm9jZXNzLmNhdGVnb3J5ID09ICJNaW5pbWFsbHkgUHJvY2Vzc2VkIikgJT4lCiAgZGlzdGluY3QoKSAgIyBSZW1vdmUgZHVwbGljYXRlcwpsZW5ndGgodW5pcXVlKGVsaWdpYmxlX29sZF9kb2dzJGlkKSkKCgojIEdldCB1bmlxdWUgSURzIGZyb20gZWFjaCB0YWJsZQpvbGRfaWRzIDwtIGRpc3RpbmN0KGVsaWdpYmxlX29sZF9kb2dzLCBpZCkKbWlkX2lkcyA8LSBkaXN0aW5jdChlbGlnaWJsZV9taWRfZG9ncywgaWQpCnlvdW5nX2lkcyA8LSBkaXN0aW5jdChlbGlnaWJsZV95b3VuZ19kb2dzLCBpZCkKCiMgRmluZCBjb21tb24gaWRzIGFjcm9zcyBhbGwgdGhyZWUgdGFibGVzCmNvbW1vbl9pZHMgPC0gaW50ZXJzZWN0KGludGVyc2VjdChvbGRfaWRzJGlkLCBtaWRfaWRzJGlkKSwgeW91bmdfaWRzJGlkKQojIEZpbmQgY29tbW9uIElEcyBhY3Jvc3MgYWxsIHRocmVlIHRhYmxlcyB1c2luZyByZWR1Y2UgYW5kIGludGVyc2VjdAojY29tbW9uX2lkcyA8LSBSZWR1Y2UoaW50ZXJzZWN0LCBsaXN0KG9sZF9pZHMkaWQsIG1pZF9pZHMkaWQsIHlvdW5nX2lkcyRpZCkpCgoKZWxpZ2libGVfZG9ncyA8LSBiaW5kX3Jvd3MoCiAgZmlsdGVyKGVsaWdpYmxlX29sZF9kb2dzLCBpZCAlaW4lIGNvbW1vbl9pZHMpLAogIGZpbHRlcihlbGlnaWJsZV9taWRfZG9ncywgaWQgJWluJSBjb21tb25faWRzKSwKICBmaWx0ZXIoZWxpZ2libGVfeW91bmdfZG9ncywgaWQgJWluJSBjb21tb25faWRzKQopCgoKZWxpZ2libGVfZG9nczFfZGF0YXRhYmxlID0gZGF0YXRhYmxlKGVsaWdpYmxlX2RvZ3MsIG9wdGlvbnMgPSBsaXN0KCksIGNsYXNzID0gImRpc3BsYXkiKQplbGlnaWJsZV9kb2dzMV9kYXRhdGFibGUKbGVuZ3RoKHVuaXF1ZShlbGlnaWJsZV9kb2dzJGlkKSkKYGBgCgoKRGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgZG9ncyB0aGF0IGhhdmUgYSBCQ1Mgb2YgNCw1LCBvciA2IGJldHdlZW4gdGhlIGFnZSBvZiAwLTMsIDQtNiAsIDcrIHRoYXQgYXJlIGdlbmVyYWxseSBoZWFsdGh5IG9uIGEgdWx0cmEgcHJvY2Vzc2VkIGRpZXQgCmBgYHtyfQojIEZpbHRlciBEaWV0X0RhdGFfQ2xlYW4gZm9yIGFnZSBhbmQgQkNTIGNvbmRpdGlvbnMKI2VsaWdpYmxlX3lvdW5nX2RvZ3MgPC0gRGlldF9EYXRhX0NsZWFuICU+JQojICBmaWx0ZXIodmlzaXQuYWdlIDwgMywgQkNTX251bWVyaWMgPCA3KQojbGVuZ3RoKHVuaXF1ZShlbGlnaWJsZV95b3VuZ19kb2dzJGlkKSkKCiMgRmlsdGVyIERpZXRfRGF0YV9DbGVhbiBmb3IgYWdlIHVuZGVyIDMgeWVhcnMgYW5kIEJDUyBiZWxvdyA3CiNlbGlnaWJsZV95b3VuZ19kb2dzIDwtIERpZXRfQ29tYmluZURhdGFfVXBkYXRlZCAlPiUKIyMgIGZpbHRlcih2aXNpdC5hZ2UgPCAzLCBiY3MgJWluJSBjKDQsNSw2KSkgJT4lCiMgIGRpc3RpbmN0KCkKI2xlbmd0aCh1bmlxdWUoZWxpZ2libGVfeW91bmdfZG9ncyRpZCkpCgplbGlnaWJsZV95b3VuZ19kb2dzIDwtIERpZXRfQ29tYmluZURhdGFfVXBkYXRlZCAlPiUKICBmaWx0ZXIodmlzaXQuYWdlIDw9IDMsICAgICAgICAgICAgICAgICMgQWdlIHVuZGVyIDMgeWVhcnMKICAgICAgICAgYmNzICVpbiUgYyg0LCA1LCA2KSwgICAgICAgICAgIyBCQ1Mgb2YgNCwgNSwgb3IgNgogICAgICAgICBhbnlfbWFqb3JfZGlhZ25vc2lzID09IDAsICAgICAjIEV4Y2x1ZGUgZG9ncyB3aXRoIGFueSBtYWpvciBkaWFnbm9zaXMKICAgICAgICAgcHJvY2Vzcy5jYXRlZ29yeSA9PSAiVWx0cmEgUHJvY2Vzc2VkIikgJT4lCiAgZGlzdGluY3QoKSAgIyBSZW1vdmUgZHVwbGljYXRlcwpsZW5ndGgodW5pcXVlKGVsaWdpYmxlX3lvdW5nX2RvZ3MkaWQpKQoKZWxpZ2libGVfbWlkX2RvZ3MgPC0gRGlldF9Db21iaW5lRGF0YV9VcGRhdGVkICU+JQogIGZpbHRlcih2aXNpdC5hZ2UgPjMgJiB2aXNpdC5hZ2UgPD0gNiwgICAgICAgICAgICAgICAgIyBiZXR3ZWVuIDQtNgogICAgICAgICBiY3MgJWluJSBjKDQsIDUsIDYpLCAgICAgICAgICAjIEJDUyBvZiA0LCA1LCBvciA2CiAgICAgICAgIGFueV9tYWpvcl9kaWFnbm9zaXMgPT0gMCwgICAgICMgRXhjbHVkZSBkb2dzIHdpdGggYW55IG1ham9yIGRpYWdub3NpcwogICAgICAgICBwcm9jZXNzLmNhdGVnb3J5ID09ICJVbHRyYSBQcm9jZXNzZWQiKSAlPiUKICBkaXN0aW5jdCgpICAjIFJlbW92ZSBkdXBsaWNhdGVzCmxlbmd0aCh1bmlxdWUoZWxpZ2libGVfbWlkX2RvZ3MkaWQpKQoKZWxpZ2libGVfb2xkX2RvZ3MgPC0gRGlldF9Db21iaW5lRGF0YV9VcGRhdGVkICU+JQogIGZpbHRlcih2aXNpdC5hZ2UgPiA3LCAgICAgICAgICAgICAgICAjIG92ZXIgNwogICAgICAgICBiY3MgJWluJSBjKDQsIDUsIDYpLCAgICAgICAgICAjIEJDUyBvZiA0LCA1LCBvciA2CiAgICAgICAgIGFueV9tYWpvcl9kaWFnbm9zaXMgPT0gMCwgICAgICMgRXhjbHVkZSBkb2dzIHdpdGggYW55IG1ham9yIGRpYWdub3NpcwogICAgICAgICBwcm9jZXNzLmNhdGVnb3J5ID09ICJVbHRyYSBQcm9jZXNzZWQiKSAlPiUKICBkaXN0aW5jdCgpICAjIFJlbW92ZSBkdXBsaWNhdGVzCmxlbmd0aCh1bmlxdWUoZWxpZ2libGVfb2xkX2RvZ3MkaWQpKQoKCiMgR2V0IHVuaXF1ZSBJRHMgZnJvbSBlYWNoIHRhYmxlCm9sZF9pZHMgPC0gZGlzdGluY3QoZWxpZ2libGVfb2xkX2RvZ3MsIGlkKQptaWRfaWRzIDwtIGRpc3RpbmN0KGVsaWdpYmxlX21pZF9kb2dzLCBpZCkKeW91bmdfaWRzIDwtIGRpc3RpbmN0KGVsaWdpYmxlX3lvdW5nX2RvZ3MsIGlkKQoKIyBGaW5kIGNvbW1vbiBpZHMgYWNyb3NzIGFsbCB0aHJlZSB0YWJsZXMKY29tbW9uX2lkcyA8LSBpbnRlcnNlY3QoaW50ZXJzZWN0KG9sZF9pZHMkaWQsIG1pZF9pZHMkaWQpLCB5b3VuZ19pZHMkaWQpCiMgRmluZCBjb21tb24gSURzIGFjcm9zcyBhbGwgdGhyZWUgdGFibGVzIHVzaW5nIHJlZHVjZSBhbmQgaW50ZXJzZWN0CiNjb21tb25faWRzIDwtIFJlZHVjZShpbnRlcnNlY3QsIGxpc3Qob2xkX2lkcyRpZCwgbWlkX2lkcyRpZCwgeW91bmdfaWRzJGlkKSkKCgplbGlnaWJsZV9kb2dzIDwtIGJpbmRfcm93cygKICBmaWx0ZXIoZWxpZ2libGVfb2xkX2RvZ3MsIGlkICVpbiUgY29tbW9uX2lkcyksCiAgZmlsdGVyKGVsaWdpYmxlX21pZF9kb2dzLCBpZCAlaW4lIGNvbW1vbl9pZHMpLAogIGZpbHRlcihlbGlnaWJsZV95b3VuZ19kb2dzLCBpZCAlaW4lIGNvbW1vbl9pZHMpCikKZWxpZ2libGVfZG9ncwoKI2VsaWdpYmxlX2RvZ3MxX2RhdGF0YWJsZSA9IGRhdGF0YWJsZShlbGlnaWJsZV9kb2dzLCBvcHRpb25zID0gbGlzdCgpLCBjbGFzcyA9ICJkaXNwbGF5IikKI2VsaWdpYmxlX2RvZ3MxX2RhdGF0YWJsZQpsZW5ndGgodW5pcXVlKGVsaWdpYmxlX2RvZ3MkaWQpKQpsZW5ndGgodW5pcXVlKGVsaWdpYmxlX2RvZ3MkaWQpKQoKd3JpdGUueGxzeChlbGlnaWJsZV9kb2dzLCBmaWxlID0gIkVsaWdpYmxlRG9ncy54bHN4Iiwgc2hlZXROYW1lID0gIkRhdGEiLCByb3dOYW1lcyA9IEZBTFNFKQpgYGAKIyBGaWx0ZXIgdGhlIGRvZ3MgYmFzZWQgb24gQWdlLCBiY3MsIGFuZCBkaWFnbm9zaXMgCgoKYGBge3J9CiMgRmlsdGVyIERpZXRfRGF0YV9DbGVhbiBmb3IgYWdlIGFuZCBCQ1MgY29uZGl0aW9ucwojZWxpZ2libGVfeW91bmdfZG9ncyA8LSBEaWV0X0RhdGFfQ2xlYW4gJT4lCiMgIGZpbHRlcih2aXNpdC5hZ2UgPCAzLCBCQ1NfbnVtZXJpYyA8IDcpCiNsZW5ndGgodW5pcXVlKGVsaWdpYmxlX3lvdW5nX2RvZ3MkaWQpKQoKIyBGaWx0ZXIgRGlldF9EYXRhX0NsZWFuIGZvciBhZ2UgdW5kZXIgMyB5ZWFycyBhbmQgQkNTIGJlbG93IDcKI2VsaWdpYmxlX3lvdW5nX2RvZ3MgPC0gRGlldF9Db21iaW5lRGF0YV9VcGRhdGVkICU+JQojIyAgZmlsdGVyKHZpc2l0LmFnZSA8IDMsIGJjcyAlaW4lIGMoNCw1LDYpKSAlPiUKIyAgZGlzdGluY3QoKQojbGVuZ3RoKHVuaXF1ZShlbGlnaWJsZV95b3VuZ19kb2dzJGlkKSkKCmVsaWdpYmxlX3lvdW5nX2RvZ3MgPC0gRGlldF9Db21iaW5lRGF0YV9VcGRhdGVkICU+JQogIGZpbHRlcih2aXNpdC5hZ2UgPD0gMywgICAgICAgICAgICAgICAgIyBBZ2UgdW5kZXIgMyB5ZWFycwogICAgICAgICBiY3MgJWluJSBjKDQsIDUsIDYpLCAgICAgICAgICAjIEJDUyBvZiA0LCA1LCBvciA2CiAgICAgICAgIHByb2Nlc3MuY2F0ZWdvcnkgPT0gIlVsdHJhIFByb2Nlc3NlZCIpICU+JQogIGRpc3RpbmN0KCkgICMgUmVtb3ZlIGR1cGxpY2F0ZXMKbGVuZ3RoKHVuaXF1ZShlbGlnaWJsZV95b3VuZ19kb2dzJGlkKSkKCmVsaWdpYmxlX21pZF9kb2dzIDwtIERpZXRfQ29tYmluZURhdGFfVXBkYXRlZCAlPiUKICBmaWx0ZXIodmlzaXQuYWdlID4zICYgdmlzaXQuYWdlIDw9IDYsICAgICAgICAgICAgICAgICMgYmV0d2VlbiA0LTYKICAgICAgICAgYmNzICVpbiUgYyg0LCA1LCA2KSwgICAgICAgICAgIyBCQ1Mgb2YgNCwgNSwgb3IgNgogICAgICAgICBwcm9jZXNzLmNhdGVnb3J5ID09ICJVbHRyYSBQcm9jZXNzZWQiKSAlPiUKICBkaXN0aW5jdCgpICAjIFJlbW92ZSBkdXBsaWNhdGVzCmxlbmd0aCh1bmlxdWUoZWxpZ2libGVfbWlkX2RvZ3MkaWQpKQoKZWxpZ2libGVfb2xkX2RvZ3MgPC0gRGlldF9Db21iaW5lRGF0YV9VcGRhdGVkICU+JQogIGZpbHRlcih2aXNpdC5hZ2UgPiA3LCAgICAgICAgICAgICAgICAjIG92ZXIgNwogICAgICAgICBiY3MgJWluJSBjKDQsIDUsIDYpLCAgICAgICAgICAjIEJDUyBvZiA0LCA1LCBvciA2CiAgICAgICAgIHByb2Nlc3MuY2F0ZWdvcnkgPT0gIlVsdHJhIFByb2Nlc3NlZCIpICU+JQogIGRpc3RpbmN0KCkgICMgUmVtb3ZlIGR1cGxpY2F0ZXMKbGVuZ3RoKHVuaXF1ZShlbGlnaWJsZV9vbGRfZG9ncyRpZCkpCgoKIyBHZXQgdW5pcXVlIElEcyBmcm9tIGVhY2ggdGFibGUKb2xkX2lkcyA8LSBkaXN0aW5jdChlbGlnaWJsZV9vbGRfZG9ncywgaWQpCm1pZF9pZHMgPC0gZGlzdGluY3QoZWxpZ2libGVfbWlkX2RvZ3MsIGlkKQp5b3VuZ19pZHMgPC0gZGlzdGluY3QoZWxpZ2libGVfeW91bmdfZG9ncywgaWQpCgojIEZpbmQgY29tbW9uIGlkcyBhY3Jvc3MgYWxsIHRocmVlIHRhYmxlcwpjb21tb25faWRzIDwtIGludGVyc2VjdChpbnRlcnNlY3Qob2xkX2lkcyRpZCwgbWlkX2lkcyRpZCksIHlvdW5nX2lkcyRpZCkKIyBGaW5kIGNvbW1vbiBJRHMgYWNyb3NzIGFsbCB0aHJlZSB0YWJsZXMgdXNpbmcgcmVkdWNlIGFuZCBpbnRlcnNlY3QKI2NvbW1vbl9pZHMgPC0gUmVkdWNlKGludGVyc2VjdCwgbGlzdChvbGRfaWRzJGlkLCBtaWRfaWRzJGlkLCB5b3VuZ19pZHMkaWQpKQoKCmVsaWdpYmxlX2RvZ3MgPC0gYmluZF9yb3dzKAogIGZpbHRlcihlbGlnaWJsZV9vbGRfZG9ncywgaWQgJWluJSBjb21tb25faWRzKSwKICBmaWx0ZXIoZWxpZ2libGVfbWlkX2RvZ3MsIGlkICVpbiUgY29tbW9uX2lkcyksCiAgZmlsdGVyKGVsaWdpYmxlX3lvdW5nX2RvZ3MsIGlkICVpbiUgY29tbW9uX2lkcykKKQoKCiNlbGlnaWJsZV9kb2dzMV9kYXRhdGFibGUgPSBkYXRhdGFibGUoZWxpZ2libGVfZG9ncywgb3B0aW9ucyA9IGxpc3QoKSwgY2xhc3MgPSAiZGlzcGxheSIpCiNlbGlnaWJsZV9kb2dzMV9kYXRhdGFibGUKbGVuZ3RoKHVuaXF1ZShlbGlnaWJsZV9kb2dzJGlkKSkKYGBgCgoKCmBgYHtyfQojIEZpbHRlciBEaWV0X0RhdGFfQ2xlYW4gZm9yIGFnZSBhbmQgQkNTIGNvbmRpdGlvbnMKI2VsaWdpYmxlX3lvdW5nX2RvZ3MgPC0gRGlldF9EYXRhX0NsZWFuICU+JQojICBmaWx0ZXIodmlzaXQuYWdlIDwgMywgQkNTX251bWVyaWMgPCA3KQojbGVuZ3RoKHVuaXF1ZShlbGlnaWJsZV95b3VuZ19kb2dzJGlkKSkKCiMgRmlsdGVyIERpZXRfRGF0YV9DbGVhbiBmb3IgYWdlIHVuZGVyIDMgeWVhcnMgYW5kIEJDUyBiZWxvdyA3CiNlbGlnaWJsZV95b3VuZ19kb2dzIDwtIERpZXRfQ29tYmluZURhdGFfVXBkYXRlZCAlPiUKIyMgIGZpbHRlcih2aXNpdC5hZ2UgPCAzLCBiY3MgJWluJSBjKDQsNSw2KSkgJT4lCiMgIGRpc3RpbmN0KCkKI2xlbmd0aCh1bmlxdWUoZWxpZ2libGVfeW91bmdfZG9ncyRpZCkpCgplbGlnaWJsZV95b3VuZ19kb2dzIDwtIERpZXRfQ29tYmluZURhdGFfVXBkYXRlZCAlPiUKICBmaWx0ZXIodmlzaXQuYWdlIDw9IDMsICAgICAgICAgICAgICAgICMgQWdlIHVuZGVyIDMgeWVhcnMKICAgICAgICAgYmNzICVpbiUgYyg3LCA4LCA5KSwgICAgICAgICAgIyBCQ1Mgb2YgNCwgNSwgb3IgNgogICAgICAgICBwcm9jZXNzLmNhdGVnb3J5ID09ICJVbHRyYSBQcm9jZXNzZWQiKSAlPiUKICBkaXN0aW5jdCgpICAjIFJlbW92ZSBkdXBsaWNhdGVzCmxlbmd0aCh1bmlxdWUoZWxpZ2libGVfeW91bmdfZG9ncyRpZCkpCgplbGlnaWJsZV9taWRfZG9ncyA8LSBEaWV0X0NvbWJpbmVEYXRhX1VwZGF0ZWQgJT4lCiAgZmlsdGVyKHZpc2l0LmFnZSA+MyAmIHZpc2l0LmFnZSA8PSA2LCAgICAgICAgICAgICAgICAjIGJldHdlZW4gNC02CiAgICAgICAgIGJjcyAlaW4lIGMoNywgOCwgOSksICAgICAgICAgICMgQkNTIG9mIDQsIDUsIG9yIDYKICAgICAgICAgcHJvY2Vzcy5jYXRlZ29yeSA9PSAiVWx0cmEgUHJvY2Vzc2VkIikgJT4lCiAgZGlzdGluY3QoKSAgIyBSZW1vdmUgZHVwbGljYXRlcwpsZW5ndGgodW5pcXVlKGVsaWdpYmxlX21pZF9kb2dzJGlkKSkKCmVsaWdpYmxlX29sZF9kb2dzIDwtIERpZXRfQ29tYmluZURhdGFfVXBkYXRlZCAlPiUKICBmaWx0ZXIodmlzaXQuYWdlID4gNywgICAgICAgICAgICAgICAgIyBvdmVyIDcKICAgICAgICAgYmNzICVpbiUgYyg3LCA4LCA5KSwgICAgICAgICAgIyBCQ1Mgb2YgNCwgNSwgb3IgNgogICAgICAgICBwcm9jZXNzLmNhdGVnb3J5ID09ICJVbHRyYSBQcm9jZXNzZWQiKSAlPiUKICBkaXN0aW5jdCgpICAjIFJlbW92ZSBkdXBsaWNhdGVzCmxlbmd0aCh1bmlxdWUoZWxpZ2libGVfb2xkX2RvZ3MkaWQpKQoKCiMgR2V0IHVuaXF1ZSBJRHMgZnJvbSBlYWNoIHRhYmxlCm9sZF9pZHMgPC0gZGlzdGluY3QoZWxpZ2libGVfb2xkX2RvZ3MsIGlkKQptaWRfaWRzIDwtIGRpc3RpbmN0KGVsaWdpYmxlX21pZF9kb2dzLCBpZCkKeW91bmdfaWRzIDwtIGRpc3RpbmN0KGVsaWdpYmxlX3lvdW5nX2RvZ3MsIGlkKQoKIyBGaW5kIGNvbW1vbiBpZHMgYWNyb3NzIGFsbCB0aHJlZSB0YWJsZXMKY29tbW9uX2lkcyA8LSBpbnRlcnNlY3QoaW50ZXJzZWN0KG9sZF9pZHMkaWQsIG1pZF9pZHMkaWQpLCB5b3VuZ19pZHMkaWQpCiMgRmluZCBjb21tb24gSURzIGFjcm9zcyBhbGwgdGhyZWUgdGFibGVzIHVzaW5nIHJlZHVjZSBhbmQgaW50ZXJzZWN0CiNjb21tb25faWRzIDwtIFJlZHVjZShpbnRlcnNlY3QsIGxpc3Qob2xkX2lkcyRpZCwgbWlkX2lkcyRpZCwgeW91bmdfaWRzJGlkKSkKCgplbGlnaWJsZV9kb2dzIDwtIGJpbmRfcm93cygKICBmaWx0ZXIoZWxpZ2libGVfb2xkX2RvZ3MsIGlkICVpbiUgY29tbW9uX2lkcyksCiAgZmlsdGVyKGVsaWdpYmxlX21pZF9kb2dzLCBpZCAlaW4lIGNvbW1vbl9pZHMpLAogIGZpbHRlcihlbGlnaWJsZV95b3VuZ19kb2dzLCBpZCAlaW4lIGNvbW1vbl9pZHMpCikKCgplbGlnaWJsZV9kb2dzM19kYXRhdGFibGUgPSBkYXRhdGFibGUoZWxpZ2libGVfZG9ncywgb3B0aW9ucyA9IGxpc3QoKSwgY2xhc3MgPSAiZGlzcGxheSIpCmVsaWdpYmxlX2RvZ3MzX2RhdGF0YWJsZQpsZW5ndGgodW5pcXVlKGVsaWdpYmxlX2RvZ3MkaWQpKQpgYGAKCgpgYGB7cn0KIyBGaWx0ZXIgRGlldF9EYXRhX0NsZWFuIGZvciBhZ2UgYW5kIEJDUyBjb25kaXRpb25zCiNlbGlnaWJsZV95b3VuZ19kb2dzIDwtIERpZXRfRGF0YV9DbGVhbiAlPiUKIyAgZmlsdGVyKHZpc2l0LmFnZSA8IDMsIEJDU19udW1lcmljIDwgNykKI2xlbmd0aCh1bmlxdWUoZWxpZ2libGVfeW91bmdfZG9ncyRpZCkpCgojIEZpbHRlciBEaWV0X0RhdGFfQ2xlYW4gZm9yIGFnZSB1bmRlciAzIHllYXJzIGFuZCBCQ1MgYmVsb3cgNwojZWxpZ2libGVfeW91bmdfZG9ncyA8LSBEaWV0X0NvbWJpbmVEYXRhX1VwZGF0ZWQgJT4lCiMjICBmaWx0ZXIodmlzaXQuYWdlIDwgMywgYmNzICVpbiUgYyg0LDUsNikpICU+JQojICBkaXN0aW5jdCgpCiNsZW5ndGgodW5pcXVlKGVsaWdpYmxlX3lvdW5nX2RvZ3MkaWQpKQoKZWxpZ2libGVfeW91bmdfZG9ncyA8LSBEaWV0X0NvbWJpbmVEYXRhX1VwZGF0ZWQgJT4lCiAgZmlsdGVyKHZpc2l0LmFnZSA8PSAzLCAgICAgICAgICAgICAgICAjIEFnZSB1bmRlciAzIHllYXJzCiAgICAgICAgIGJjcyAlaW4lIGMoNCwgNSwgNiksICAgICAgICAgICMgQkNTIG9mIDQsIDUsIG9yIDYKICAgICAgICAgcHJvY2Vzcy5jYXRlZ29yeSA9PSAiVWx0cmEgUHJvY2Vzc2VkIikgJT4lCiAgZGlzdGluY3QoKSAgIyBSZW1vdmUgZHVwbGljYXRlcwpsZW5ndGgodW5pcXVlKGVsaWdpYmxlX3lvdW5nX2RvZ3MkaWQpKQoKZWxpZ2libGVfbWlkX2RvZ3MgPC0gRGlldF9Db21iaW5lRGF0YV9VcGRhdGVkICU+JQogIGZpbHRlcih2aXNpdC5hZ2UgPjMgJiB2aXNpdC5hZ2UgPD0gNiwgICAgICAgICAgICAgICAgIyBiZXR3ZWVuIDQtNgogICAgICAgICBiY3MgJWluJSBjKDcsIDgsIDkpLCAgICAgICAgICAjIEJDUyBvZiA3IDggb3IgOQogICAgICAgICBwcm9jZXNzLmNhdGVnb3J5ID09ICJVbHRyYSBQcm9jZXNzZWQiKSAlPiUKICBkaXN0aW5jdCgpICAjIFJlbW92ZSBkdXBsaWNhdGVzCmxlbmd0aCh1bmlxdWUoZWxpZ2libGVfbWlkX2RvZ3MkaWQpKQoKZWxpZ2libGVfb2xkX2RvZ3MgPC0gRGlldF9Db21iaW5lRGF0YV9VcGRhdGVkICU+JQogIGZpbHRlcih2aXNpdC5hZ2UgPiA3LCAgICAgICAgICAgICAgICAjIG92ZXIgNwogICAgICAgICBiY3MgJWluJSBjKDcsIDgsIDkpLCAgICAgICAgICAjIEJDUyBvZiA3IDggb3IgOQogICAgICAgICBwcm9jZXNzLmNhdGVnb3J5ID09ICJVbHRyYSBQcm9jZXNzZWQiKSAlPiUKICBkaXN0aW5jdCgpICAjIFJlbW92ZSBkdXBsaWNhdGVzCmxlbmd0aCh1bmlxdWUoZWxpZ2libGVfb2xkX2RvZ3MkaWQpKQoKCiMgR2V0IHVuaXF1ZSBJRHMgZnJvbSBlYWNoIHRhYmxlCm9sZF9pZHMgPC0gZGlzdGluY3QoZWxpZ2libGVfb2xkX2RvZ3MsIGlkKQptaWRfaWRzIDwtIGRpc3RpbmN0KGVsaWdpYmxlX21pZF9kb2dzLCBpZCkKeW91bmdfaWRzIDwtIGRpc3RpbmN0KGVsaWdpYmxlX3lvdW5nX2RvZ3MsIGlkKQoKIyBGaW5kIGNvbW1vbiBpZHMgYWNyb3NzIGFsbCB0aHJlZSB0YWJsZXMKY29tbW9uX2lkcyA8LSBpbnRlcnNlY3QoaW50ZXJzZWN0KG9sZF9pZHMkaWQsIG1pZF9pZHMkaWQpLCB5b3VuZ19pZHMkaWQpCiMgRmluZCBjb21tb24gSURzIGFjcm9zcyBhbGwgdGhyZWUgdGFibGVzIHVzaW5nIHJlZHVjZSBhbmQgaW50ZXJzZWN0CiNjb21tb25faWRzIDwtIFJlZHVjZShpbnRlcnNlY3QsIGxpc3Qob2xkX2lkcyRpZCwgbWlkX2lkcyRpZCwgeW91bmdfaWRzJGlkKSkKCgplbGlnaWJsZV9kb2dzIDwtIGJpbmRfcm93cygKICBmaWx0ZXIoZWxpZ2libGVfb2xkX2RvZ3MsIGlkICVpbiUgY29tbW9uX2lkcyksCiAgZmlsdGVyKGVsaWdpYmxlX21pZF9kb2dzLCBpZCAlaW4lIGNvbW1vbl9pZHMpLAogIGZpbHRlcihlbGlnaWJsZV95b3VuZ19kb2dzLCBpZCAlaW4lIGNvbW1vbl9pZHMpCikKCgplbGlnaWJsZV9kb2dzNF9kYXRhdGFibGUgPSBkYXRhdGFibGUoZWxpZ2libGVfZG9ncywgb3B0aW9ucyA9IGxpc3QoKSwgY2xhc3MgPSAiZGlzcGxheSIpCmVsaWdpYmxlX2RvZ3M0X2RhdGF0YWJsZQpsZW5ndGgodW5pcXVlKGVsaWdpYmxlX2RvZ3MkaWQpKQpgYGAKCmBgYHtyfQojIFN1bW1hcml6ZSB0aGUgZGF0YSB0byBnZXQgY291bnRzIG9mIGRpYWdub3NlcyBieSBzdHVkeV95ZWFyCmNhcmRpb19zdW1tYXJ5IDwtIERpZXRfQ29tYmluZURhdGFfVXBkYXRlZCAlPiUKICAgZmlsdGVyKCFpcy5uYShhbnlfY2FyZGlvKSkgJT4lCiAgZ3JvdXBfYnkoc3R1ZHlfeWVhciwgYW55X2NhcmRpbykgJT4lCiAgc3VtbWFyaXplKEZyZXF1ZW5jeSA9IG4oKSwgLmdyb3VwcyA9ICdkcm9wJykKCiMgRW5zdXJlIHRoZSAnYW55JyBjb2x1bW4gaXMgYSBmYWN0b3IgZm9yIGJldHRlciBwbG90dGluZwpjYXJkaW9fc3VtbWFyeSRhbnlfY2FyZGlvIDwtIGZhY3RvcihjYXJkaW9fc3VtbWFyeSRhbnlfY2FyZGlvLCBsZXZlbHMgPSBjKDAsIDEpLCBsYWJlbHMgPSBjKCJObyBEaWFnbm9zaXMiLCAiRGlhZ25vc2lzIikpCgoKY2FyZGlvX3N1bW1hcnlfZGF0YXRhYmxlID0gZGF0YXRhYmxlKGNhcmRpb19zdW1tYXJ5LCBvcHRpb25zID0gbGlzdCgpLCBjbGFzcyA9ICJkaXNwbGF5IikKY2FyZGlvX3N1bW1hcnlfZGF0YXRhYmxlCgojIENyZWF0ZSB0aGUgYmFyIHBsb3QKY2FyZGlvX3Bsb3QgPC0gZ2dwbG90KGNhcmRpb19zdW1tYXJ5LCBhZXMoeCA9IHN0dWR5X3llYXIsIHkgPSBGcmVxdWVuY3ksIGZpbGwgPSBhbnlfY2FyZGlvKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpICsgIyAnZG9kZ2UnIHBvc2l0aW9uIHRvIHBsYWNlIGJhcnMgc2lkZSBieSBzaWRlCiAgbGFicyh0aXRsZSA9ICJGcmVxdWVuY3kgb2YgQ2FyZGlvdmFzY3VsYXIgRGlhZ25vc2VzIGJ5IFN0dWR5IFllYXIiLAogICAgICAgeCA9ICJTdHVkeSBZZWFyIiwKICAgICAgIHkgPSAiTnVtYmVyIG9mIERvZ3MiLAogICAgICAgZmlsbCA9ICJDYXJkaW8gRGlhZ25vc2lzIikgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsgIyBPcHRpb25hbDogQWRkcyBjb2xvcgogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSwgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIpICMgSW1wcm92ZSByZWFkYWJpbGl0eSBvZiB4LWF4aXMgbGFiZWxzCgojIERpc3BsYXkgdGhlIHBsb3QKcHJpbnQoY2FyZGlvX3Bsb3QpCgojIENvbnZlcnQgdG8gYW4gaW50ZXJhY3RpdmUgUGxvdGx5IHBsb3QKaW50ZXJhY3RpdmVfZmlnNCA8LSBnZ3Bsb3RseShjYXJkaW9fcGxvdCkKCiMgUHJpbnQgdGhlIGludGVyYWN0aXZlIHBsb3QKaW50ZXJhY3RpdmVfZmlnNAoKYGBgCgoKYGBge3J9CnNhdmUoaW50ZXJhY3RpdmVfZmlnMSxpbnRlcmFjdGl2ZV9maWcyLGludGVyYWN0aXZlX2ZpZzMsaW50ZXJhY3RpdmVfZmlnNCxpbnRlcmFjdGl2ZV9maWc1LGludGVyYWN0aXZlX2ZpZzYsIGZpbGUgPSAifi9Ecm9wYm94IChFZGlzb25fTGFiQFVHQSkvUHJvamVjdHMvdmV0L0RlYW5uYS9Hb2xkZW5fRGF0YS9maWd1cmVzNC5SRGF0YSIpCgoKc2F2ZSh1bmlxdWVfY291bnRfZGF0YXRhYmxlLCBCQ1NfZGF0YXRhYmxlLCBwcm9jZXNzaW5nX2RhdGF0YWJsZSxlbGlnaWJsZV9kb2dzMV9kYXRhdGFibGUsZWxpZ2libGVfZG9nczNfZGF0YXRhYmxlLGVsaWdpYmxlX2RvZ3M0X2RhdGF0YWJsZSxtaW5vcl9kaWFnbm9zaXNfc3VtbWFyeV9kYXRhdGFibGUsbWFqb3JfZGlhZ25vc2lzX3N1bW1hcnlfZGF0YXRhYmxlCixkaWFnbm9zaXNfc3VtbWFyeV9kYXRhdGFibGUsIGZpbGUgPSAifi9Ecm9wYm94IChFZGlzb25fTGFiQFVHQSkvUHJvamVjdHMvdmV0L0RlYW5uYS9Hb2xkZW5fRGF0YS90YWJsZXM0LlJEYXRhIikKCgpgYGAKCgoKCg==